插座.如何使用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。


您的问题有几种解决方案,但没有一种可以在不修改服务器端的情况下正确使用。

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

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

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

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

最新更新