.NET NetworkStream закрыт, как убедиться, что все данные прочитаны?

У меня открыто TCP-соединение и чтение с использованием NetworkStream.BeginRead(). Как только соединение закрывается на любом конце, вызывается обратный вызов, и объект потока становится бесполезным - как говорится в документации, EndRead() выдает IOException или ObjectDisposedException в зависимости от того, на каком конце было прервано соединение.

Гарантируется ли отсутствие каких-либо данных, которые я пропускаю только между последним успешным EndRead (и повторным BegingRead) и отключением, особенно если я делаю это на своем конце? Если это не так, в случае, если я завершаю соединение, нужно ли мне вручную выполнять NetworkStream.Read() при отключении, чтобы убедиться, что ничего не осталось непрочитанным?


person Stockhausen    schedule 18.06.2010    source источник


Ответы (1)


Шаблон, используемый в этом случае, заключается в использовании BeginRead для чтения потока (точно так же, как вы делаете) и для обработки случая «больше данных в потоке» в методе обратного вызова.
Метод обратного вызова вызывает EndRead и собирает данные считываются из потока (обычно путем добавления их к экземпляру StringBuilder) и затем снова вызывает BeginRead. Как только EndRead вернет 0 байтов, это ваша гарантия того, что из потока больше не будет данных для чтения.

Вот документация, которая может оказаться полезной: Использование асинхронного клиента розетки

Я заметил, что нигде конкретно не указано, что возврат 0 байтов был гарантией, поэтому я понимаю ваше замешательство здесь, но пример очень ясен, что это ваш сигнал прекратить чтение.

person Task    schedule 24.06.2010
comment
У-у-у! Я знаю вещи, которые верны, но о которых абсолютно никто не знает достаточно, чтобы подтвердить или опровергнуть! Э-э, подождите минутку, почему я этому рад? - person Task; 17.09.2010
comment
Я собираюсь воскресить это в надежде, что, возможно, на этот (очень связанный) вопрос будет дан ответ: как EndRead может произвести 0 прочитанных байтов, если единственный способ EndRead вызывается в обратном вызове BeginRead, который требует передачи данных для выполнения ? Должен ли я просто отправить ответ с нулевым байтом? - person Brandon; 22.05.2014
comment
Итак, теперь вы говорите об записи в поток, а не о чтении из него. Это немного другое. У вас есть открытый вопрос, на который можно сослаться? По сути, вам не нужно специально записывать нулевые байты, вам просто нужно закончить свой ответ. - person Task; 26.05.2014
comment
У меня нет открытого вопроса, нет. Я протестировал запись данных в поток и вызов BeginRead на другой стороне после того, как данные были прочитаны кусками. Когда данных больше нет, BeginRead заблокируется, и обратный вызов никогда не будет вызван. В основном: EndRead не может возвращать нулевые байты. В итоге я добавил заголовок, описывающий длину сообщения, чтобы обойти это. - person Brandon; 26.05.2014