Чтение расщепленных TCP-пакетов - PullRequest
2 голосов
/ 13 марта 2011

Я написал большую часть кода для обработки входящих пакетов для моего сервера. Формат для пакетов всегда 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 Ответ

1 голос
/ 13 марта 2011

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...