TCP套接字:双重消息

时间:2012-05-07 02:24:21

标签: python sockets double message

我在python中遇到套接字问题。

我有一个TCP服务器和客户端,它在while 1循环中发送对方数据。

它在struct模块(struct.pack("hh", mousex, mousey))中打包了2个short。但有时当recv在另一台计算机上的数据时,似乎有两条消息被粘在一起。这是nagle的算法吗?

enter image description here

这到底发生了什么?提前谢谢。

3 个答案:

答案 0 :(得分:1)

为了确保我必须看到实际代码,但听起来您希望sendn个字节在接收器上显示为n字节全部时间,每一次。

TCP流不能以这种方式工作。这是一个“流”协议,而不是像UDP或STCPRDS那样的“数据报”(面向记录)。

对于固定数据大小的协议(或任何预先可预测下一个块大小的协议),您只需在循环中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是一个可能的原因,但不是唯一的原因。