我正在使用原始套接字接口(import socket
)在Python 2.7.5中编写应用程序。
我需要知道是否有一种方法可以注册某种事件,或者如果TCP套接字连接仍然连接并建立,则可以定期轻松测试。
我发现的大多数建议都说“只是尝试从中读取;如果关闭则会出现错误或没有字节。”但是,有时我还没准备好read
,但我仍然想知道套接字是否关闭,所以例如我可以立即手动重新连接。
此外,来自套接字的read
将删除从缓冲区读取的字节,因此read
只是为了测试连接“活跃性”似乎不可行。
有一个后台线程来检查连接活跃性对我来说没关系。该线程可以每秒检查一次,看看连接是否有效;如果它被删除,那么它可以调用一个函数,或设置一个变量或其他东西,以便应用程序知道连接已关闭。知道它关闭的原因(由同行重置,超时等)会更有用......
对此有何建议?
答案 0 :(得分:18)
使用本教程建议的select
http://docs.python.org/2/howto/sockets.html#non-blocking-sockets
如果一个套接字在输出可读列表中,那么你可以像我们一样接近确定该套接字上的recv会返回一些内容。可写列表的想法相同。你将能够发送一些东西。也许不是你想要的全部,但有些东西总比没有好。 (实际上,任何合理健康的套接字都将以可写方式返回 - 它只是意味着出站网络缓冲区空间可用。)
...如果那些输入插座列表中的某个位置已经死亡,那么选择将会失败。
这是我经常使用的流程
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')
答案 1 :(得分:0)
尝试:
if len(recv) == 0:
print("disconnected fired !")