TcpClient.BeginRead / TcpClient.EndRead не выдает исключение, когда интернет отключен - PullRequest
0 голосов
/ 01 февраля 2011

Я использую TcpListener, чтобы принять и прочитать с TcpClient. Проблема в том, что при чтении с TcpClient, TcpClient.BeginRead / TcpClient.EndRead не выдает исключение при отключении интернета. Выдает исключение, только если клиентский процесс завершен или соединение закрыто сервером или клиентом.

Ответы [ 4 ]

1 голос
/ 01 февраля 2011

Система обычно не имеет возможности узнать, что соединение разорвано.Единственный надежный способ узнать это - попытаться что-то отправить.Когда вы делаете это, пакет отправляется, затем теряется или возвращается, и ваша система знает, что соединение больше не доступно, и сообщает вам о проблеме по коду ошибки или исключению (в зависимости от среды).Чтение обычно недостаточно, поскольку чтение только проверяет состояние входного буфера и не отправляет пакет на удаленную сторону.

1 голос
/ 01 февраля 2011

Если вы хотите знать, когда меняется состояние сети, вы можете подписаться на событие System.Net.NetworkInformation.NetworkChange.NetworkAvailabilityChanged. Это не относится только к Интернету, только к локальной сети.

EDIT

Извините, я неправильно понял. Понятие «подключенный» действительно не существует, чем больше вы думаете об этом. Этот пост проделывает большую работу, чтобы вдаваться в подробности об этом. В TcpClient есть свойство Connected, но MSDN говорит (выделено мое):

Потому что только свойство Connected отражает состояние соединения с самой последней операции вы должен попытаться отправить или получить сообщение для определения текущего государство. После неудачной отправки сообщения это свойство больше не возвращает true. Обратите внимание, что это поведение предусмотрено дизайном. Вы не можете надежно проверить состояние связь, потому что во времени между тестом и отправкой / получением, связь могла быть потеряна. Ваш код должен предполагать, что сокет подключен, и изящно обрабатывать сбой передачи.

По сути, единственный способ проверить клиентское соединение - это попытаться отправить данные. Если это проходит, вы подключены. Если это не удается, вы не.

1 голос
/ 01 февраля 2011

Насколько я знаю, низкоуровневые розетки не уведомляют вас в таких случаях. Вы должны предоставить собственную реализацию тайм-аута или периодически пинговать сервер.

0 голосов
/ 01 февраля 2011

Я не думаю, что вы хотели бы, чтобы BeginRead и EndRead вызывали исключения, поскольку они должны использоваться в многопоточных сценариях.

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

...