Чтение расщепленных TCP-пакетов

Я написал большую часть кода для обработки входящих пакетов для моего сервера. Формат для пакетов всегда int/int/int/string/string, а первое int - это размер пакета. Мне нужно найти какой-то способ проверить и увидеть, прибыл ли весь пакет или мне нужно дождаться, пока не появятся новые фрагменты, однако, учитывая то, как я написал свой код, я не могу придумать хороший способ. Любая помощь была бы великолепна, так как мой мозг, вероятно, обдумывает это

private void ReadClientPacket(object client)
{
    TcpClient tcpClient = (TcpClient)client;
    NetworkStream clientStream = tcpClient.GetStream();

    while (true)
    {
        try
        {
            int packetsize;

            // Create a new Packet Object and fill out the data from the incoming TCP Packets
            RCONPacket packet = new RCONPacket();

            using (BinaryReader reader = new BinaryReader(clientStream))
            {
                // First Int32 is Packet Size
                packetsize = reader.ReadInt32();

                packet.RequestId = reader.ReadInt32();
                packet.ServerDataSent = (RCONPacket.SERVERDATA_sent)reader.ReadInt32();

                Console.WriteLine("Packet Size: {0} RequestID: {1} ServerData: {2}", packetsize, packet.RequestId, packet.ServerDataSent);

                // Read first and second String in the Packet (UTF8 Null Terminated)
                packet.String1 = ReadBytesString(reader);
                packet.String2 = ReadBytesString(reader);

                Console.WriteLine("String1: {0} String2: {1}", packet.String1, packet.String2);
            }

            switch (packet.ServerDataSent)
            {
                case RCONPacket.SERVERDATA_sent.SERVERDATA_AUTH:
                {
                    ReplyAuthRequest(packet.RequestId, clientStream);
                    break;
                }
                case RCONPacket.SERVERDATA_sent.SERVERDATA_EXECCOMMAND:
                {
                    ReplyExecCommand();
                    break;
                }
                default:
                {
                    break;
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            break;
        }
    }

    tcpClient.Close();
}

1 ответ

Решение

То, что у вас есть, должно работать, так как основной поток будет ждать больше данных. То есть если бы ты позвонил clientStream.ReadByte и нет доступных байтов, метод будет блокироваться до тех пор, пока не поступят данные или пока поток не будет закрыт - в этом случае, вероятно, отключен сервером.

BinaryReader будет до тех пор, пока не будет достаточно данных для удовлетворения запроса на чтение, поэтому код должен работать как положено.

Другие вопросы по тегам