背景:
二进制协议通常定义给定大小的帧。如果所有内容都在单个缓冲区中接收,则struct
模块很擅长解析。
问题:
TCP套接字是流式的。从套接字读取的数据不能超过请求的字节数,但可能会返回较少的字节。因此,该代码不可靠:
def readnbytes(sock, n):
return sock.recv(n) # can return less than n bytes
单纯的解决方法:
def readnbytes(sock, n):
buff = b''
while n > 0:
b = sock.recv(n)
buff += b
if len(b) == 0:
raise EOFError # peer socket has received a SH_WR shutdown
n -= len(b)
return buff
若我们请求大量字节并且数据非常分散,可能不太有效率,因为我们会反复重新分配新的字节缓冲区。
问题:
如何从流套接字可靠地接收恰好 n 个字节而无需重新分配的风险?
参考资料:
这些相关问题提供了一些提示,但没有提供简单明确的答案: