Когда я отправляю пакет через TCP, он разделяется на два пакета.

StackOverflow https://stackoverflow.com/questions/769045

  •  12-09-2019
  •  | 
  •  

Вопрос

Я разрабатываю приложение на C#, используя модель сервер-клиент, где сервер отправляет клиенту массив байтов с растровым изображением, клиент загружает его на экран, отправляет серверу «ОК», а сервер отправляет другое изображение и так далее.

Длина буфера изображения зависит, обычно она составляет от 60 до 90 КБ, но я видел, что это не имеет значения.Если я поставлю клиент и сервер на один компьютер, используя localhost, все будет работать нормально.Сервер выполняет BeginSend, а клиент — EndReceive, и передается весь буфер.

Однако сейчас я тестирую это в беспроводной сети, и происходит следующее:

  • Сервер отправляет изображение.
  • Вызывается функция обратного вызова data_received на клиенте, но осталось прочитать только 1460 байт (MTU — почему?не должно быть только в UDP?)
  • Функция обратного вызова data_received на клиенте вызывается снова, теперь уже с остальной частью буфера (будь то 1000 байт или 100 килобайт)...

Всегда так, принимается первый пакет размером 1460 байт, а потом второй пакет содержит остальное.

Я могу обойти это, объединив оба полученных массива байтов, но это кажется неправильным.Я даже не уверен, почему это происходит.Это какие-то ограничения в сети?Почему же тогда C# не ждет передачи всех данных?Я имею в виду, это TCP, мне не о чем беспокоиться, верно?

В любом случае, любая помощь будет здорово!
Ваше здоровье

Это было полезно?

Решение

Это TCP — вы должны относиться к данным как к транслировать.Вас не должно волновать, как поток разбивается на пакеты, или делать предположения об этом.

Если вам нужно получить один «блок» данных, самый простой способ сделать это надежно — добавить к нему префикс длины (например,как 32-битное значение).Вы читаете длину (замечая, что даже эти байты мог быть разделены на несколько пакетов), а затем многократно читаться (синхронно или асинхронно), отмечая, сколько вы читаете каждый раз, пока не прочтете все данные.

Другие советы

Почитайте 9.2.4

Анализируя протокол прикладного уровня, вы не можете предполагать, что каждый TCP-пакет содержит ровно одно сообщение прикладного уровня.Одно сообщение прикладного уровня можно разделить на несколько пакетов TCP.

добавляя к ответу Джона:

int offset = 0;
int imagesize = 512;
byte[] buffer = new byte[512];

tcpChannel.Read(buffer, offset, imagesize);
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top