【问题标题】:Python TCP Sockets: How to know if a specific connection has sent informationPython TCP Sockets:如何知道特定连接是否已发送信息
【发布时间】:2016-08-04 09:06:23
【问题描述】:

我有一个多线程 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 来检查套接字上是否有要接收的内容,但这无助于我参考具体的连接。

【问题讨论】:

    标签: python multithreading sockets tcp


    【解决方案1】:

    是的,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)
    

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

    【讨论】:

    • Plus OP 不必使用单独的线程来接受新连接。这可以(并且应该)在同一个select 循环中完成。另请注意,为了获得更好的性能,OP 应该切换到 epoll(或围绕它的一些包装器,例如 gevent)。
    • 感谢您提供有关这方面的信息,不过,请注意,self.all_connections 是连接对象列表,而不是套接字,这会一样吗?
    • @Harvey:在这种情况下,连接一个套接字。 socket.accept() 返回一个元组,其中包含一个到新接受的连接的套接字对象及其地址。
    • 太棒了,我现在会在我的应用程序中使用select.select()
    猜你喜欢
    • 1970-01-01
    • 2018-10-23
    • 2020-10-24
    • 2017-08-12
    • 1970-01-01
    • 2015-11-12
    • 1970-01-01
    • 2020-06-08
    • 2019-11-10
    相关资源
    最近更新 更多