Когда я отправляю пакет через TCP, он разделяется на два пакета - PullRequest
6 голосов
/ 20 апреля 2009

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

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

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

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

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

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

В любом случае, любая помощь будет великолепна!
Приветствия

Ответы [ 3 ]

14 голосов
/ 20 апреля 2009

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

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

5 голосов
/ 20 апреля 2009

Прочитайте 9.2.4

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

0 голосов
/ 07 июня 2009

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

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

tcpChannel.Read(buffer, offset, imagesize);
...