Как я могу обнаружить разъединение сокета? / Как я могу вызвать socket.recv с таймаутом? - PullRequest
4 голосов
/ 15 мая 2011

Я использую gevent patched socket для подключения к потоковому серверу, и я использую соединение adsl.

Я не контролирую сервер, но в моих тестах, если я остановлю сервер, я смогу обнаружить отключение, просто проверив, является ли результат от recv пустой строкой, но если я отключу мой adsl модем recvникогда не выходит.Если я просто отсоединяю сетевой кабель моего компьютера, он также не возвращает пустую строку, но когда я снова подключаю его, он возвращает все, что сервер отправил за это время, поэтому я предполагаю, что маршрутизатор или модем оставляют соединение открытым для меняи буферизация потока при отключенном сетевом кабеле.

Я попытался установить socket.SO_RCVTIMEO на несколько секунд, но он не обнаружил отключение, recv продолжает «блокировать» вечно.Это gevent, поэтому он блокирует только greenthread, но мне нужно как можно скорее обнаружить это отключение, чтобы попытаться восстановить соединение.

Ответы [ 2 ]

4 голосов
/ 15 мая 2011

Используйте тайм-ауты, предоставленные gevent, например, в операторе with:

with Timeout(5, False):
    data = sock.recv()

или в качестве функции:

data = gevent.with_timeout(5, sock.recv, timeout_value="")
2 голосов
/ 16 мая 2011

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

если вы действительно хотите обнаружить отключение как можно скорее, то, я думаю, вам следует просто каждую секунду анализировать состояние сети os (ifconfig / ipconfig) / или использовать события os и делать то, что вы хотите, когда обнаруживаете отключение сети. *

...