|
Вопрос # 4 569/ вопрос открыт / |
|
Здравствуйте, уважаемые эксперты!
Скажите пожалуйста, как в C# проверить подключен ли еще Socket к TCPListener'y? После того, как я сделал TCPClient.Close() в приложении клиента, как узнать в серверной части, отрубилось ли соединение TCPListener'a с сокетом?
Заранее спасибо!
 |
Вопрос задал: webkent (статус: 2-ой класс)
Вопрос отправлен: 8 сентября 2010, 13:22
Состояние вопроса: открыт, ответов: 2.
|
Ответ #1. Отвечает эксперт: Вадим К
Здравствуйте, webkent!
Правильный ответ - никак. На сервере можно узнать по таймауту подключения.
Если клиент-сервер свой, то делают так называемые keep-alive пакеты. то есть клиент обязан послать серверу раз в сколько то минут спецпакет. Сервер ответить. Или наоборот. Если ответ не пришел за какое то определенное время - значит клиент отвалился.
А вот само закрытие делают так - вначале отсылают специальный пакет завершения соединения, дожидаются ответа и закрывают сокет.
Так делают все нормальные протоколы.
Если же сервер/клиент ничего не шлет, то разрыв соединения можно "не заметить" до нескольких часов (все зависит от настроек).
 |
Ответ отправил: Вадим К (статус: Академик)
Время отправки: 8 сентября 2010, 13:32
Оценка за ответ: 5
Комментарий к оценке: Спасибо, Вадим, буду делать сам!
|
Ответ #2. Отвечает эксперт: bugmenot
А теперь - правильный ответ :-)
Деталей реализации в CLR не знаю, опишу на низком уровне
Протокол TCP реализует управление состоянием соединения и уведомляет о закрытии.
Close должно вызывать след. обмен http://www.firewall.cx/pictures/tcp-analysis-section-4-3.gif в этом случае другой конец получает статус WSAEDISCON (10101) - http://msdn.microsoft.com/en-us/library/ms740668(VS.85).aspx
Спецификация описывает второй возможный способ форсированного закрытия соединения, тогда посылается флаг RST вместо FIN и статус будет WSAECONNRESET (10054) - там же
4.2.2.13 Closing a Connection http://tools.ietf.org/html/rfc1122#section-4.2.2.13
 |
Ответ отправил: bugmenot (статус: 3-ий класс)
Время отправки: 8 сентября 2010, 17:29
|
Мини-форум вопроса
Всего сообщений: 1; последнее сообщение — 8 сентября 2010, 17:58; участников в обсуждении: 1.
|
Вадим К (статус: Академик), 8 сентября 2010, 17:58 [#1]:
to bugmenot: в идеальном случае оно то так и работает. Но в действительности, пользователи имеют "наглось" отваливаться и без вызова закрытия сокета. И тут начинаются танцы с бубном. Если после отваливания клиента сервер ничего не пишет в сокет, то узнать, жив ли он - не может. и по той же rfc 1122 - до 4 минут.
В Windows же это время может быть ещё больше.
Итого. В идеале то оно может и работает хорошо, на практике нужно делать в протоколе либо keep-alive пакеты и явно конец обмена.
Галочка "подтверждения прочтения" - вселенское зло.
|
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|