使用python中的select从多个连接接收数据

时间:2017-09-14 15:22:54

标签: python sockets

我对使用recv()时如何继续致电select()感到困惑。此代码不完整,但它演示了此问题。让我们假设我们从每个连接(10,20mb)接收到相当数量的数据。

在调用recv()后获得所需的字节数之前,是否应继续使用select()进行循环?

while True:
    r,w,e = select.select(r_ready, w_ready, [], timeout)
    for client in r:
        if client == sock:
            acceptConnection(sock)
        else:
            chunks = []
            bytesRead = 0
            while bytesRead < desiredBytes:
                chunk = client.recv(1024)
                bytesRead += len(chunk)

或者你应该在每次select()循环之后只调用一次recv()吗?

clientBuffers = {}
while True:
    r,w,e = select.select(r_ready, w_ready, [], timeout)
    for client in r:
        if client == sock:
            acceptConnection(sock)
        else:
            chunk = client.recv(1024)
            clientBuffers[client].append(chunk)

1 个答案:

答案 0 :(得分:1)

  

你应该使用recv()继续循环,直到得到所需的数字   调用select()后的字节数?

一般来说,没有;因为你无法知道需要多长时间。 (例如,对于你所知道的,客户端可能不会发送(或者网络可能不会传递)整个所需字节序列,直到它发送序列中的第一个字节一小时;这意味着如果你留在一个循环调用recv ()直到你获得所有字节,然后所有其他客户端可能很长时间都不会从你的服务器得到任何响应 - 显然不是多客户端服务器的理想行为!)

相反,只需从当前的recv()中获取尽可能多的字节,如果你还没有收到足够的字节来执行操作,那么将接收到的字节存储在某个地方的缓冲区中以便稍后再返回常规select()调用。 select()应该是您阻止的事件循环中唯一的位置。强烈建议您将所有套接字设置为非阻塞,以确保您不会在recv()调用中意外阻止。