Проблема чтения с TCPClient - PullRequest
1 голос
/ 30 мая 2011

Я делаю простое клиентское приложение на C # и обнаружил проблему.

Серверное приложение отправляет строку в формате "<number> <param> <param>" и т. Д. Другими словами, первый символ - это целое число, а остальные - что угодно, все разделены одним пробелом.

Проблема, с которой я сталкиваюсь при чтении этой строки, заключается в том, что моя программа сначала читает строку с помощью, а затем при следующем прочтении я получаю остальную часть сообщения. Например, если бы я делал переписку о том, что я получаю, это выглядело бы так: (если он отправляет «1 0 0 0»)

1
 0 0 0 

(РЕДАКТИРОВАТЬ: форматирование, кажется, не позволяет этого. 1 стоит в отдельной строке, остальные должны быть в строке ниже, включая пробел, предшествующий первому 0)

У меня закончились идеи, как это исправить. Вот метод (я прокомментировал некоторые вещи, которые я попробовал): http://pastebin.com/0bXC9J2f

РЕДАКТИРОВАТЬ (снова): Я забыл, что, кажется, он работает нормально, когда я нахожусь в отладке, и просто прошагиваю все по шагам, поэтому я не могу найти источник проблемы таким образом.

Ответы [ 2 ]

8 голосов
/ 30 мая 2011

TCP основан на потоке, а не на сообщениях. Один Read может содержать любую из следующих альтернатив:

  • Небольшая часть сообщения
  • Половина сообщения
  • Точно одно сообщение
  • Полтора сообщения
  • Два сообщения

Таким образом, вам нужно использовать какой-то метод, чтобы увидеть, пришло ли полное сообщение. Наиболее распространенные методы:

  • Добавить нижний колонтитул (например, пустую строку), который указывает конец сообщения
  • Добавить заголовок фиксированной длины, содержащий длину сообщения
1 голос
/ 30 мая 2011

Если ваш протокол прямой TCP, вы не можете отправлять сообщения, строки или что-либо еще, кроме октетов, (байтов) потоков. У вашей «строки» есть ноль в конце? Если это так, вам нужно добавлять полученные данные до тех пор, пока не прибудет ноль, тогда у вас есть ваше сообщение.

Если это ваша проблема, то вы должны закодировать свой протокол так, чтобы он работал независимо от того, сколько вызовов чтения сделано в сокете, например. если сервер отправляет строку с нулевым символом в конце [99 байтов данных + # 0], ваш протокол должен иметь возможность собрать правильную строку, если 100 байтов возвращены за один вызов, 1 байт получен за 100 вызовов или что-либо в между ними.

Rgds, Martin

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