Чтение разделенных пакетов 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();
}

person Community    schedule 13.03.2011    source источник


Ответы (1)


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

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

person Jim Mischel    schedule 13.03.2011