python - socket.recv() 接收的字节数少于预期
问题描述
这段代码下载了大部分文件,但不是所有文件(在一个while循环内)知道我做错了什么吗?
data = csocket.recv(1024)
with open(filename, 'wb') as file_to_save:
while data:
file_to_save.write(data)
time.sleep(.008)
data = csocket.recv(1024)
if len(data) < 1024:
break
下载 38,616 字节大小的文件时,此代码下载大约 600 字节。
解决方案
通常 recv() 函数不保证返回您“请求”的字节总数。该参数只是您期望接收的最大字节数,但如果缓冲区中可用,该函数可以返回比这更少的字节数。这是来自https://docs.python.org/3/howto/sockets.html的实现
def myreceive(self):
chunks = []
bytes_recd = 0
while bytes_recd < MSGLEN:
chunk = self.sock.recv(min(MSGLEN - bytes_recd, 2048))
if chunk == b'':
raise RuntimeError("socket connection broken")
chunks.append(chunk)
bytes_recd = bytes_recd + len(chunk)
return b''.join(chunks)
如您所见,该函数重复 recv() 直到达到预期的字节数。每个块到达后,新的 recv() 请求作为最大字节数MSGLEN – bytes_recd
。min() 用于将每个块的接收字节数限制为 2048。当 recv() 函数返回 0 字节(chunk == b'')时,表示对方关闭了连接。
对于您的情况,len(data)
can a 有时会返回小于 1024。您的中断条件应该是if len(data) < 1:
推荐阅读
- java - 具有不确定方法签名的抽象方法
- cloudflare - Cloudflare URL 转发特定 url
- postgresql - 如何在 postgres 中使用 Oracle 函数 SYS_EXTRACT_UTC
- rdf - 我想使用 protege 读取 AGROVOC 核心 rdf,当我在 protege 中打开文件时,它不显示文件中的任何元素
- servicenow - 如何限制 itil 用户仅查看其公司/组的事件?立即服务
- c# - 如果按钮文本值为 2,则按钮应为禁用模式
- reactjs - Redux 存储数据在表格中显示的问题
- filter - 如何访问 panflute 中的全局变量(Pandoc 过滤器)
- c# - 在 UI 线程上使用计时器更新标签文本,而不阻塞 UI
- angular - 如何在单独的按钮上发布上传的文件,而不是在 Kendo Angular Upload 中自动上传