NetworkStream.DataAvailable видит буферизованные данные? - PullRequest
4 голосов
/ 03 октября 2008

Знает ли NetworkStream.DataAvailable, является ли буфер отправки отправителя пустым? Или это просто указывает, есть ли в буфере чтения получателя данные? Мое предположение последнее ...

В частности, для некоторой работы с сокетом, включающей текущий разговор, я в настоящее время использую префикс длины, чтобы получатель точно знал, сколько данных находится в текущем пакете; однако мне прислали патч с предложением использовать вместо него NetworkStream.DataAvailable. Меня беспокоит то, что это просто скажет мне, что получил получатель, а не то, что отправитель изначально отправил, но я не эксперт по сокетам.

Я не прав? Или это префикс длины?

(обратите внимание, я не могу просто прочитать (), пока поток не будет закрыт, так как несколько пакетов отправляются по одному соединению, и очень важно, чтобы я обрабатывал каждую партию как отдельную; даже если он буферизуется и удаляется) разговор прервется).

Ответы [ 2 ]

5 голосов
/ 03 октября 2008

Одна сторона соединения не будет знать, пуст ли буфер отправки другой стороны.

DataAvailable только указывает, есть ли входящие данные для чтения. Вы можете использовать это до Read(), но оно само по себе не дает нужной вам информации. Он не сообщает вам начало и конец каждой партии.

Раньше я кодировал беседу туда-сюда и использовал в данных префиксы длины. Я написал вспомогательные функции, которые читают точное количество байтов (порций за раз) и не более.

Единственная альтернатива значениям длины пакета в потоке - это какой-то способ проверки входящих данных и распознавания начала и конца пакетов.

2 голосов
/ 03 октября 2008

Если вам необходимо знать, когда получатель получил все данные для определенного сообщения, вам определенно необходимо указать префикс длины.

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

struct Header
{
  int packetIdentifier;
  int protocolVersion;
  int messageType;
  int payloadSize;
}

Идентификатор позволяет вам определить, есть ли у вас действительное сообщение вашего типа протокола. Версия позволяет вам пересмотреть ваш протокол. Тип сообщения - это тип сообщения (то есть: CommsOnline). Размер полезной нагрузки - это размер тела сообщения.

...