我在python中遇到套接字问题。
我有一个TCP服务器和客户端,它在while 1
循环中发送对方数据。
它在struct模块(struct.pack("hh", mousex, mousey)
)中打包了2个short。但有时当recv
在另一台计算机上的数据时,似乎有两条消息被粘在一起。这是nagle的算法吗?
这到底发生了什么?提前谢谢。
答案 0 :(得分:1)
为了确保我必须看到实际代码,但听起来您希望send
个n
个字节在接收器上显示为n
字节全部时间,每一次。
TCP流不能以这种方式工作。这是一个“流”协议,而不是像UDP或STCP或RDS那样的“数据报”(面向记录)。
对于固定数据大小的协议(或任何预先可预测下一个块大小的协议),您只需在循环中recv()
就可以在流套接字上构建自己的“数据报式接收器”直到你得到n
个字节:
def recv_n_bytes(socket, n):
"attempt to receive exactly n bytes; return what we got"
data = []
while True:
have = sum(len(x) for x in data)
if have >= n:
break
want = n - have
got = socket.recv(want)
if got == '':
break
return ''.join(data)
(未经测试; python 2.x代码;不一定高效;等等)。
答案 1 :(得分:1)
我同意其他海报,“TCP就是这样做的”。 TCP保证您的字节以正确的顺序到达,但不保证它们到达的块的大小。我想补充一点,TCP也允许将单个发送拆分成多个recv,甚至例如拆分aabb, ccdd进入aab,bcc,dd。
我把这个模块放在一起处理python中的相关问题: http://stromberg.dnsalias.org/~strombrg/bufsock.html 它属于开源许可,由UCI拥有。它已经在CPython 2.x,CPython 3.x,Pypy和Jython上进行了测试。
HTH
答案 2 :(得分:0)
您可能不会认为数据可以从本地套接字读取,其大小与在其他源端发送的大小相同。正如您所看到的,这有时通常是正确的,但绝不是可靠的。更确切地说,TCP保证的是,一端的内容最终将从另一端出来,为了没有任何遗漏,或者如果无法通过协议中内置的方式实现,例如重试,那么整个事情将会破坏误差的。
Nagle是一个可能的原因,但不是唯一的原因。