Context:
It is common that a binary protocol defines frames of a given size. The struct
module is good at parsing that, provided everything has been received in a single buffer.
Problem:
TCP sockets are streams. A read from a socket cannot give more bytes than requested but can return less. So this code is not reliable:
def readnbytes(sock, n):
return sock.recv(n) # can return less than n bytes
The naive workaround:
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
may not be efficient, because if we ask a large number of bytes, and the data if very fragmented, we will repeatedly re-allocate a new byte buffer.
Question:
How is it possible to reliably receive exactly n bytes from a stream socket with no risk of re-allocation?
References:
Those other questions are related, and do give hints, but none give a simple and clear answer:
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…