Python:检测套接字何时因任何原因断开连接?

时间:2013-06-30 02:13:37

标签: python sockets

我正在使用原始套接字接口(import socket)在Python 2.7.5中编写应用程序。

我需要知道是否有一种方法可以注册某种事件,或者如果TCP套接字连接仍然连接并建立,则可以定期轻松测试。

我发现的大多数建议都说“只是尝试从中读取;如果关闭则会出现错误或没有字节。”但是,有时我还没准备好read,但我仍然想知道套接字是否关闭,所以例如我可以立即手动重新连接。

此外,来自套接字的read将删除从缓冲区读取的字节,因此read只是为了测试连接“活跃性”似乎不可行。

有一个后台线程来检查连接活跃性对我来说没关系。该线程可以每秒检查一次,看看连接是否有效;如果它被删除,那么它可以调用一个函数,或设置一个变量或其他东西,以便应用程序知道连接已关闭。知道它关闭的原因(由同行重置,超时等)会更有用......

对此有何建议?

2 个答案:

答案 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 !")