Как определить отключение от розетки? / Как мне вызвать socket.recv с тайм-аутом?

Я использую патч-сокет gevent для подключения к потоковому серверу, и я использую соединение ADSL.

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

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


person Luiz Geron    schedule 15.05.2011    source источник


Ответы (2)


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

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

или как функция:

data = gevent.with_timeout(5, sock.recv, timeout_value="")
person truppo    schedule 15.05.2011

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

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

person RoeeK    schedule 15.05.2011