Получение tcp-запроса с неизвестным размером сообщения

#c# #tcp

#c# #tcp

Вопрос:

У меня настроен прослушиватель tcp, в который поступает сообщение неизвестного размера. Я не уверен, какова наилучшая практика, когда дело доходит до обработки неизвестных размеров сообщений. Вот код:

 TcpListener _server = new TcpListener(_localAddr, _port);
_server.Start();
while (true)
{
    if (_server.Pending())
    {
        Byte[] bytes = new Byte[256];//Works fine if message under this size
        string data = string.Empty;
        _client = _server.AcceptTcpClient();
        NetworkStream stream = _client.GetStream();
        int i;
        while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
        {
            data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
            data = data.ToUpper();
            //Do stuff with data
        }
}
  

Итак, вы заметите, что я могу изменить размер байтов массива с 256 на что-то большее, но я не знаю, есть ли лучший способ, чем просто установить размер на то, что, как я знаю, достаточно велико. Если сообщение меньше 256, оно работает нормально.

Заранее спасибо за любую помощь

Ответ №1:

Если длина сообщений не является постоянной, служба, отправляющая вам сообщения, должна отправлять вам в начале каждого сообщения несколько байтов (обычно 4, потому что Int32 — это 32 бита, то есть 4 байта), которые будут указывать длину сообщения.

Когда вы получаете сообщение, вы должны сначала прочитать эти 4 байта, затем после их анализа вы узнаете длину сообщения и сможете создать массив байтов соответствующего размера.

Теперь вы можете прочитать в этот массив само сообщение.

Комментарии:

1. Итак, клиент сказал мне следующее: каждое XML-сообщение, которое Matrix отправляет на сервер интерфейса, будет заканчиваться байтом EOT (0x04). Итак, это в конце сообщения, а не в начале. Не уверен, как это в конце поможет мне.

2. Существует другой подход, кроме приведенного выше, в этом подходе вы получите разделитель, который будет указывать, что это конец сообщения, в этом случае вы должны перебирать байт за байтом в сообщении, пока не дойдете до разделителя, вы не можете узнать конец сообщения, прежде чем получитек нему. Итак, для начала вам следует выделить некоторую память для хранения сообщения, но если при переборе байтов вы заметите, что сообщение больше, чем выделенная память, вам следует увеличить его.

3. Да, это то, что я сейчас собираюсь сделать, спасибо. Просто хотел убедиться, что нет более простого способа.