2016-10-08 5 views
-1

Я делаю небольшую программу, и я пытаюсь обработать клиентское соединение. Когда клиент отключается, он отправляет сообщение об отключении, и я обрабатываю это. Но когда клиент закрывается с силой (сетевое соединение потеряно, задача убита, исключение ..) Сервер все еще видит клиента как подключенного. Теперь я пытаюсь немедленно обновить эту информацию, после того как клиент больше не подключен, его следует удалить. Я не могу просто пинговать его время от времени, не так ли? Что делать, если есть передача, и я вмешиваюсь в команду ping?C# Socket - Как проверить, отключен ли клиент?

TL; DRHow я знаю, если мой клиент больше не подключен?

+0

TCP является _designed_, чтобы предотвратить обнаружение многих типов разъединения. Помимо изящного закрытия, только если удаленная конечная точка принудительно закрыла сокет, вы получите сообщение об ошибке, и даже тогда, если у вас есть чтение в ожидании на сокете. В противном случае ошибки не будут обнаружены, если вы не напишете в сокет. Обратите внимание, что TCP включает опцию «keep-alive», которая периодически будет записывать в сокет, и поэтому может выполнять это автоматически. Обратите также внимание на то, что попытка обнаружения отключений, как правило, является плохой идеей **, поскольку она отрицает всю точку отказоустойчивости TCP. –

+0

См. Отмеченный дубликат для более подробного обсуждения вопроса. –

ответ

0

Когда сокет изящно выключается, вы получите сообщение об отключении (возврат нулевых байтов из попытки чтения) ... хорошие времена!

Если удаленная задача была убита, а сокет не был изящно выключен (или какой-либо другой сценарий, когда клиент ушел, но сервер все еще прослушивает), у вас есть «half open socket». Обнаружение их может быть сложным в зависимости от сценария. TCP has a keep-alive mechanism, который должен обнаружить это (в основном, в немобильных сетях и если они включены). Для мобильных подключений (в частности, изящный GPRS/Edge) вы обнаружите, что даже keep-alives не всегда работают, и любая попытка отправить данные просто возвращает успех. В этом случае вы должны установить правильное соединение при автоматическом таймауте, если клиент не отправил вам какие-либо данные ... Конечно, всегда есть ситуации, когда клиент пытается повторно подключиться, но у вас уже есть сокет сидя там

0

Попробуйте это. Меня устраивает.

private static bool IsSocketConnected(Socket socket) 
{ 
    try 
    { 
     return !(socket.Poll(1, SelectMode.SelectRead) && socket.Available == 0); 
    } 
    catch (SocketException) { return false; } 
} 
+0

Это также возвращает true, если нет данных для чтения, но сокеты все еще связаны, насколько я знаю. Это не то, что я хочу точно .. Но спасибо! –

Смежные вопросы