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

2024-06-14 11:28:46 发布

您现在位置:Python中文网/ 问答频道 /正文

从服务器到客户端接收数据时遇到问题。我有以下客户端函数,试图从服务器接收数据。服务器使用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()继续读取其他丢失的数据?谢谢您。


Tags: 数据函数服务器客户端datasizedefsocket
1条回答
网友
1楼 · 发布于 2024-06-14 11:28:46

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

首先要注意这些行

if part <buff_size:
      break;

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

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

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


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

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

例如,如果您使用HTTP,那么服务器在body之前发送这个头Content-Length: 12345,因此现在作为客户机,您知道您只需要读取12345字节(您的缓冲区不必那么大,但是有了这个信息,您将知道在读取它之前需要循环多少次)。

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

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

相关问题 更多 >