一次检索套接字中的所有响应

时间:2013-09-25 20:35:20

标签: python sockets

我正在编写一个基于Python套接字的客户端服务器程序。 客户端向服务器发送命令,服务器响应。 但是现在,一些客户端可以向其他客户端广播消息,因此客户端可以同时收到多个响应。

data = s.recv(1024)

上面的代码行将只从服务器检索一个响应。 但如果我像这样使用while循环

while True:
    data = s.recv(1024)
    if not data: break

实际上,data=s.recv(1024)会在没有数据时阻止程序。 我不想阻止该程序,并希望一次检索连接中可用的所有响应。有谁能找到解决方案?谢谢。

3 个答案:

答案 0 :(得分:3)

您可以使用select module等待套接字可读或直到超时为止;然后,您可以执行其他处理。例如:

while True:
    # If data can be received without blocking (timeout=0), read it now
    ready = select.select([s], [], [], 0)
    if s in ready[0]:
        data = s.recv(1024)
        # Process data
    else:
        # No data is available, perform other tasks

答案 1 :(得分:0)

您可以使套接字无阻塞。这样,它将检索所有收到的响应,如果没有,它将返回。当然,在非阻塞的情况下,您必须定期重试。

您可以使用setblocking()方法使套接字无阻塞:

s.setblocking(0)

另一种选择是使用另一个线程来处理接收部分。这样,您的主线程可以继续执行其主要任务,并仅在收到消息时才对其执行操作。

答案 2 :(得分:0)

您可以使用socket.setblockingsocket.settimeout

import socket
import sys

HOST = 'www.google.com'   
PORT = 80             
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.setblocking(0)

s.sendall('Hello, world')
try:
    data = s.recv(1024)
except:
    print 'Oh noes! %s' % sys.exc_info()[0]
s.close()

socket.recv有两个参数,第二个是一组标志。如果您使用的是Linux系统,则可以man recv查看可以提供的标记列表及其相应的错误。

最后,一般情况下,即使您同时遵循协议,也不能知道另一方完成向您发送数据(除非您控制双方) 。我认为正确的方法是使用超时,并在发送重置后退出(如何执行此操作取决于您使用的协议)。