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

Socket. How to receive all data with socket.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() 可以继续读取其他丢失的数据?谢谢。

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

首先注意这些行

if part <buff_size:
      break;

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

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

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


您的问题有多种解决方案,但 none 无需修改服务器端即可正确使用。

作为客户,您必须知道什么时候停止阅读。但是唯一知道它的方法是服务器是否做了一些特别的事情并且你会理解它。这称为通信协议。您必须为您 send/receive.

的数据添加含义

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

某些二进制协议可能会发送前 2 或 4 个字节的内容大小。这在客户端也很容易解释。

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