0

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

data = s.recv(1024)

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

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

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

4

3 回答 3

3

您可以使用该select模块等待套接字可读或超时;然后您可以执行其他处理。例如:

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
于 2013-09-25T20:57:38.233 回答
0

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

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

s.setblocking(0)

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

于 2013-09-25T20:52:33.780 回答
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可以提供可以提供的标志列表及其相应的错误。

最后,一般来说,即使你们都遵循协议,您也无法真正知道对方是否已完成向您发送数据(除非您同时控制双方)。我相信正确的方法是使用超时,并在发送重置后退出(您如何执行此操作将取决于您使用的协议)。

于 2013-09-25T20:53:53.080 回答