Python:检测套接字何时因任何原因断开连接?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17386487/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python: detect when a socket disconnects for any reason?
提问by fdmillion
I'm writing an app in Python 2.7.5 using the raw socket interface (import socket
).
我正在使用原始套接字接口 ( import socket
)在 Python 2.7.5 中编写应用程序。
I need to know if there's a way I can either register some sort of event, or easily test at a regular interval, if a TCP socket connection is still connected and established.
我需要知道是否有一种方法可以注册某种事件,或者轻松地定期测试,如果 TCP 套接字连接仍然连接并建立。
Most of the advice I've found says things like "just try to read from it; if it's closed you'll get an error or no bytes." However, sometimes I'm not ready to read
from it but I still want to know if the socket gets closed, so for example I can manually reconnect immediately.
我发现的大多数建议都说“只是尝试从中读取;如果它关闭,您将收到错误或没有字节。” 但是,有时我还没有准备好,read
但我仍然想知道套接字是否关闭,因此例如我可以立即手动重新连接。
Also, read
ing from the socket would remove the bytes read from the buffer, so read
ing simply to test for connection "liveness" doesn't seem feasible.
此外,read
从套接字 ing 会删除从缓冲区读取的字节,因此read
仅测试连接“活跃度”似乎不可行。
Having a background thread to check for connection liveness would be OK with me. That thread could check say once per second to see if the connection is live; if it is dropped, then it could call a function, or set a variable or some other thing so that the app knows the connection closed. Knowing WHY it closed (reset by peer, timeout, etc) would be even more useful....
有一个后台线程来检查连接活跃度对我来说没问题。该线程可以每秒检查一次以查看连接是否有效;如果它被删除,那么它可以调用一个函数,或设置一个变量或其他一些东西,以便应用程序知道连接已关闭。知道它为什么关闭(由对等重置、超时等)会更有用....
Any advice on this?
对此有何建议?
回答by Steve Zhan
Use select
like this tutorial suggested
http://docs.python.org/2/howto/sockets.html#non-blocking-sockets
使用select
本教程建议
http://docs.python.org/2/howto/sockets.html#non-blocking-sockets
If a socket is in the output readable list, you can be as-close-to-certain-as-we-ever-get-in-this-business that a recv on that socket will return something. Same idea for the writable list. You'll be able to send something. Maybe not all you want to, but something is better than nothing. (Actually, any reasonably healthy socket will return as writable - it just means outbound network buffer space is available.)
... if somewhere in those input lists of sockets is one which has died a nasty death, the select will fail.
如果一个套接字在输出可读列表中,您可以非常确定,因为我们曾经在这个业务中获得过该套接字上的 recv 将返回一些东西。可写列表的想法相同。你将能够发送一些东西。也许不是您想要的全部,但有总比没有好。(实际上,任何合理健康的套接字都会以可写形式返回——这仅意味着出站网络缓冲区空间可用。)
...如果在这些输入套接字列表中的某个地方是一个不幸死亡的套接字,则选择将失败。
This is the flow I usually use
这是我通常使用的流程
import select
import socket
ip = '127.0.0.1'
port = 80
conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
conn.connect((ip, port))
while True:
try:
ready_to_read, ready_to_write, in_error = \
select.select([conn,], [conn,], [], 5)
except select.error:
conn.shutdown(2) # 0 = done receiving, 1 = done sending, 2 = both
conn.close()
# connection error event here, maybe reconnect
print 'connection error'
break
if len(ready_to_read) > 0:
recv = conn.recv(2048)
# do stuff with received data
print 'received:', recv
if len(ready_to_write) > 0:
# connection established, send some stuff
conn.send('some stuff')