Может ли случиться так, что сокет-клиент закрывает соединение, а сервер этого не знает? - PullRequest
3 голосов
/ 15 октября 2011

Может ли случиться так, что клиент сокета закрывает соединение, а сервер этого не знает?Я получил несколько ошибок на событие BeginReceive () в C #.Как проверить, жив ли клиент и в каких местах моей программы было бы лучше разместить эти проверки?

Ответы [ 2 ]

3 голосов
/ 15 октября 2011

Если вы говорите о протоколе, размещенном поверх TCP, да, это может произойти. TCP не требует отправки пакетов для поддержания связи. Поэтому, если пакеты, закрывающие соединение, не доходят до сервера, сервер может подумать, что клиент все еще там, даже после того, как клиент закрыл соединение.

Поскольку это хорошо известное свойство TCP, каждый протокол, наложенный поверх TCP, должен это учитывать. Так что, если вы просто будете следовать протоколу, у вас не будет проблем.

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

1 голос
/ 15 октября 2011

Существует несколько видов «закрытых соединений» при программировании с помощью сокетов.(Я буду использовать производные от BSD имена системных вызовов для операций с сокетами, надеюсь, они сохранили схожие имена в изменениях в C #.)

  • Клиентская программа закрывает сокет с помощью shutdown() или close().Когда это произойдет, TCP отправит пакет FIN на ваш сервер.Это будет отображаться как закрытый сокет на вашем сервере, когда вы попытаетесь прочитать за пределами последнего байта данных, отправленных клиентом.Следующее read(), вероятно, вызовет исключение или ошибку.(Зависит от среды.) Это условие обычно доступно интерфейсам в стиле опроса (например, select(2) или poll(2)), поэтому ваш стандартный обработчик цикла событий может обнаружить клиентские выходы и обработать их.

  • Клиентская программа может неожиданно завершить работу.В этом случае реализация TCP клиента, вероятно, будет отправлять FIN пакетов, но она может не находиться в «ожидаемом» месте во входном парсере вашего приложения.Будьте готовы к обработке нулевых байтов или EOF чтений, которые указывают на преждевременное завершение работы приложения.

  • Хост клиента может неожиданно умереть.В этом случае реализация TCP клиента не сможет отправить пакет FIN на ваш сервер, и вы вообще не будете получать никаких уведомлений о том, что клиентское соединение было разорвано.Вы можете включить опцию сокета TCP SO_KEEPALIVE, но по крайней мере в Linux по умолчанию используется системное время, равное двум часам неактивности перед отправкой тестов активности активности.

    Если система возвращаетсяЕсли приложение работает «быстро», ваше приложение будет получать либо пакеты TCP RST в ответ, либо Silence , если Stateful Firewall настроен на DROP пакетов, которые не соответствуют разрешенным или инициированнымтранспортные потоки.Случай RST может быть обнаружен аналогично пакетам FIN.Тишина отброшенных пакетов может быть обнаружена только с помощью схемы пакетов активности активности на уровне приложения.

Так что лучше всего встроить пакет подтверждения активности некоторого типа на временной интервал.это приемлемо для вас.(Например, IRC использует пакеты PING и PONG, чтобы гарантировать, что клиенты по-прежнему подключены к серверам - сетевые администраторы настраивают время между проверками.)

Сколько времени вы будете проходить между пингами иколичество неудачных пакетов ping для приема в значительной степени зависит от вашего приложения - возможно, вы захотите подождать двадцать минут, прежде чем заметить и удалить отключенного клиента, или вы захотите заметить и удалить отключенного клиента только через двадцать секунд.Длительность зависит от рабочей среды (20 секунд не будет работать для марсохода, но может быть в десять раз больше для видеоигры от первого лица, подключенного к локальной сети) и пропускной способности сети, доступной для «административных издержек», подобных этой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...