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

Nic*_*llo 4 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
Run Code Online (Sandbox Code Playgroud)

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

fre*_*ish 7

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

首先注意这几行

if part <buff_size:
      break;
Run Code Online (Sandbox Code Playgroud)

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

此外,如果您的服务器发送大小为 倍数的内容,buff_size则该if部分将永远不会得到满足,并且将.recv()永远挂起。

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


有几种解决方案,您的问题,但没有一个人可以不正确的modyfing服务器端使用。

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

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

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

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