Python TCP套接字:如何知道特定连接是否已发送信息

时间:2016-08-04 09:06:24

标签: python multithreading sockets tcp

我有一个多线程Python 3应用程序,在线程#1上接受TCP套接字通信。线程#2将检查所有当前连接是否有任何要接收的内容,然后采取相应措施。

所以,目前我有一个名为all_connections的列表,它是一个已接受套接字连接对象的列表。

使用for connection in all_connections:我可以遍历所有连接对象。我知道我使用conn.recv(256)来检查是否有任何东西可以在这个套接字上恢复。这会阻止循环,直到有东西可以接收吗?我事先设置了conn.setblocking(1),虽然我不确定这是否是最好的解决方法:

以下是一些示例代码:

线程1

self.all_connections = [] # init a list to hold connection objs
while 1:
    try:
        conn, address = self.socket.accept()
        conn.setblocking(1) # non blocking
    except Exception as e:
        continue
    self.all_connections.append(conn) # Save the connection object

线程2

while True:
    for connection in self.all_connections:
        received = connection.recv(256)
return

所以,我只对实际发送过某些东西的连接感兴趣,因为我最有可能发回一些东西。

我知道我可以使用select.select来检查套接字上是否有任何内容可以接收,但这并不能帮助我引用特定的连接。

1 个答案:

答案 0 :(得分:2)

是的,read()会阻止;这是默认行为。调用socket.setblocking(1)实际上会启用阻止,这与您想要的相反。 setblocking(False)将设置非阻止模式。非阻塞套接字上的I / O要求您使用异常处理。

更好的方法是,你已经朝着正确的方向前进,就是使用select()。事实上,您确实知道哪个套接字发送了数据,因为select()返回可用于读取,写入或具有错误状态的套接字列表。您向select()传递了您感兴趣的套接字列表,并返回可用于I / O的套接字。这是函数签名:

select(...)
    select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)

所以线程2中的代码看起来像这样:

from select import select

while True:
      rlist, wlist, xlist = select(self.all_connections, [], [])
      for connection in rlist:
          received = connection.recv(256)

以上代码仅检查所有连接列表中的可读套接字,并从准备好的那些中读取数据。读取不会阻止。

相关问题