Возможно ли обнаружить разъединение TCP-сокета в Python? - PullRequest
0 голосов
/ 25 ноября 2018

Я экспериментирую с Python для socketserver.TCPServer, чтобы посмотреть, как он работает.

Я думаю, что я понял большинство вещей, но остается один вопрос - как обнаружить внезапные отключения клиента, и еслиэто даже возможно.

Что я видел до сих пор, так это то, что если я напишу простой TCPServer и подключусь к нему через telnet, то после отключения telnet TCPServer будет знать, что клиент отключен.Ясно, что он получает сообщение TCP, сообщающее, что клиент отключается.Это замечательно.

Я пошел еще дальше и вместо того, чтобы закрывать процесс telnet на клиенте, я отправил ему SIGKILL, чтобы убить процесс, даже не дав ему очиститься (скажите серверу, что он отключается).Даже тогда сервер знает, что клиент ушел сразу.Похоже, что ОС клиента, а не процесс telnet, отправляет сообщение TCP FIN / RST, чтобы сообщить серверу, что клиент ушел.Также замечательно.

Затем я сделал еще один шаг, и, хотя telnet-клиент был подключен к моему TCPServer, я сказал iptables на клиенте прекратить общение с сервером.Теперь на сервер не было отправлено абсолютно никакого сообщения о том, что клиент исчез.В этот момент мой TCPServer не смог сказать, что клиент ушел.

Я знаю, что могу установить socket.setdefaulttimeout (), чтобы запретить recv () бесконечно блокировать ожидание сообщения от клиента,Проблема в том, что тайм-аут будет срабатывать, если клиент просто некоторое время молчит (не отправляет серверу никаких сообщений), или если клиент внезапно исчезает.

Так что мой вопросзаключается в следующем: когда сокет подключен между сервером и клиентом, а клиент полностью исчезает, не отправляя TCP FIN или RST, сервер может каким-либо образом узнать, что клиент ушел (в отличие от того, который все еще существует, ноне отправлять сообщения)?Или есть какое-то сердцебиение, когда клиент перестает отвечать на основной способ сообщить, что клиент ушел?

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

Хотя я в настоящее время работаю с Python, я полагаю, что это скорее общий сетевой вопрос, чем специфичный для Python.

Обновление: для всех, кого интересует, это - это то, чем я закончил.Есть несколько улучшений, которые могут быть сделаны, например, добавление if __name__ == "__main__" и обработка сообщений длиннее 1024 байтов, но если разрешить подключение клиентов и обнаружение их исчезновения, похоже, что это работает довольно хорошо.

1 Ответ

0 голосов
/ 25 ноября 2018

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

Единственный способ убедиться, что узел все еще доступен, - это иметь какое-то сердцебиение.Это можно сделать либо на уровне приложения, либо на уровне TCP - используя TCP keep-alive.Обычно системы предлагают способ не только включить поддержку TCP для каждого сокета, но и настроить частоту отправки пакета keep-alive, когда сокет простаивает, т. Е. Как быстро приложение может обнаружить, что однорангового узла больше нет.,Чтобы узнать подробности о том, как это сделать в Python, см. Как изменить таймер поддержки активности tcp с помощью скрипта Python? .

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