请参阅以下内容。
我有两个通过套接字进行通信的程序。我正在尝试将数据块从一个发送到另一个。这一直在使用一些测试数据,但与其他测试数据失败了。
s.sendall('%16d' % len(data))
s.sendall(data)
print(len(data))
发送到
size = int(s.recv(16))
recvd = ''
while size > len(recvd):
data = s.recv(1024)
if not data:
break
recvd += data
print(size, len(recvd))
一端:
s = socket.socket()
s.connect((server_ip, port))
和另一个:
c = socket.socket()
c.bind(('', port))
c.listen(1)
s,a = c.accept()
在我的最新测试中,我发送了一个7973903字节块,接收器报告的大小为7973930.
为什么数据块被27字节收到?
还有其他问题吗?
Python 2.7或2.5.4如果重要。
编辑:啊哈 - 我可能正在阅读发送缓冲区的末尾。如果剩余字节小于1024,我应该只读取剩余字节数。这种数据传输是否有标准技术?我感觉我正在重新发明轮子。
EDIT2:通过阅读系列中的下一个文件,我搞砸了。我正在发送file1,最后一个块是997字节。然后我发送file2,所以file1末尾的recv(1024)读取file2的前27个字节。
我将开始另一个关于如何做得更好的问题。
谢谢大家。询问和阅读评论帮助我集中注意力。
答案 0 :(得分:2)
首先,行
size = int(s.recv(16))
可能读取少于16个字节 - 我不太可能,我会批准,但可能取决于网络缓冲区如何对齐。 recv()
调用参数是最大值,是您愿意接收的数据量的限制。但是你可能只收到一个字节。一旦至少有一个字节到达,操作系统通常会给你一个控制权,可能是(取决于操作系统和CPU的繁忙程度)等待另一个几毫秒,以防第二个数据包到达时带有一些其他数据,这样就可以了只需要叫醒你一次而不是两次。
所以你想要说(做最简单的循环;其他变种是可能的):
data = ''
while len(data) < 16:
more = s.recv(16 - len(data))
if not more:
raise EOFError()
data += more
这确实是一个几乎每个人重新发明的轮子,因为它经常需要。并且你自己的代码需要它第二次:你的while
循环需要它的recv()
倒计时,要求更小和更小的限制,直到它最终收到了所承诺的字节数,并且没有更多。