Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 4 569

Раздел: C++
/ вопрос открыт /

Здравствуйте, уважаемые эксперты!
Скажите пожалуйста, как в C# проверить подключен ли еще Socket к TCPListener'y? После того, как я сделал TCPClient.Close() в приложении клиента, как узнать в серверной части, отрубилось ли соединение TCPListener'a с сокетом?

Заранее спасибо!

webkent Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: 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 пакеты и явно конец обмена.
Галочка "подтверждения прочтения" - вселенское зло.

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

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:52
Выполнено за 0.03 сек.