我正在使用gevent patched socket连接到流媒体服务器而我正在使用adsl连接。
我不控制服务器,但在我的测试中,如果我停止服务器,我可以通过检查recv的结果是否为空字符串来检测断开,但如果我关闭我的adsl调制解调器,则recv永远不会退出。如果我只是断开我的计算机的网络电缆,它也不会返回空字符串,但是当我重新连接它时,它会返回服务器在此期间发送的所有内容,所以我猜测路由器或调制解调器正在保持连接为我打开在我的网线断开连接时缓冲流。
我尝试将socket.SO_RCVTIMEO设置为几秒钟,但它没有检测到断开连接,recv继续“阻塞”。这是gevent,因此它只会阻止greenthread,但我需要尽快检测到这种断开连接,以便我可以尝试重新连接。
答案 0 :(得分:4)
使用gevent提供的超时,例如在with-statement中:
with Timeout(5, False):
data = sock.recv()
或作为一种功能:
data = gevent.with_timeout(5, sock.recv, timeout_value="")
答案 1 :(得分:2)
它没有检测到断开,因为没有任何断开,TCP“连接”仍然存在并且假设是可靠的。例如,如果您拔下LAN电缆,然后重新插上,连接仍然可以正常工作。
如果你真的想尽快检测断开连接,那么我猜你应该每秒解析os网络状态(ifconfig / ipconfig)/或使用os事件,并在检测到网络断开连接时执行你想要的操作。