插座。如何使用socket.recv()接收所有数据?

时间:2017-01-11 16:59:47

标签: python sockets recv

我在从服务器到客户端接收数据时遇到问题。我有以下客户端函数尝试从服务器接收数据。服务器使用socket.sendall (data)函数发送的数据大于buff_size,因此我需要一个循环来读取所有数据。

def receiveAll (sock):
    data = ""
    buff_size = 4096
    while True: 
       part = sock.recv (buff_size)
       data + = part
       if part <buff_size:
          break;
    return data

我遇到的问题是,在第一次迭代后(读取第一个4096mb),在第二次迭代中,程序被阻塞,等待part = sock.recv (buff_size)中的其他数据。我如何才能recv()继续读取其他丢失的数据?谢谢。

1 个答案:

答案 0 :(得分:3)

你的解释是错误的。您的代码读取从服务器获取的所有数据。它只是不知道它应该停止侦听传入的数据。它不知道服务器发送了它所拥有的一切。

首先要注意这些行

if part <buff_size:
      break;

非常错误。首先,您要将字符串与int进行比较(在Python3.x中会引发异常)。但即使你的意思是if len(part) <buff_size:,这仍然是错误的。因为首先在流媒体中间可能存在延迟,因此您只会阅读比buff_size小的片段。你的代码将停在那里。

此外,如果您的服务器发送的内容大小为buff_size的倍数,那么if部分将永远不会满足,并且会永久挂在.recv()上。

旁注:不要使用分号;。这是Python。

您的问题有多种解决方案,但可以正确使用 none ,而不会影响服务器端。

作为客户,您必须知道何时停止阅读。但了解它的唯一方法是,如果服务器做了一些特殊的事情,你会理解它。这称为通信协议。您必须为发送/接收的数据添加含义。

例如,如果您使用HTTP,那么服务器会在正文之前发送此标头Content-Length: 12345,所以现在作为客户端您知道只需要读取12345个字节(您的缓冲区不会必须要那么大,但有了这些信息,你就会知道在阅读之前你必须循环多少次。)

例如,某些二进制协议可以以前2或4个字节发送内容的大小。这也可以在客户端轻松解释。

更简单的解决方案是:只需让服务器在发送所有数据后关闭连接。然后,您只需在代码中添加支票if not part: break