Python Socket: 发送和接收16字节

4 投票
1 回答
6060 浏览
提问于 2025-04-16 22:18

请看下面的编辑内容。

我有两个程序,它们通过套接字进行通信。我想把一块数据从一个程序发送到另一个程序。用一些测试数据时,这个过程是正常的,但用其他数据时就出问题了。

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字节,我应该只读取剩余的字节数。对于这种数据传输,有没有标准的方法?我感觉我在重复造轮子。

编辑2:我搞错了,正在读取系列中的下一个文件。我发送的是file1,最后一个块是997字节。然后我发送file2,所以在file1结束时的recv(1024)读取了file2的前27个字节。

我会再开一个问题,问问怎么做得更好。

谢谢大家。提问和阅读评论帮助我理清了思路。

1 个回答

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()逐渐减少请求的字节数,直到最终准确接收到承诺的字节数,而不会多接收到任何字节。

撰写回答