【问题标题】:TCP Sockets: Double messagesTCP 套接字:双重消息
【发布时间】:2012-05-07 02:24:21
【问题描述】:

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

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

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

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

【问题讨论】:

  • 不,这不是 Nagle 的算法。 TCP 不复制数据。您必须发布一些代码,以便人们可以告诉您错误在哪里。

标签: python sockets double message


【解决方案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】:

    为了确保我必须查看实际代码,但听起来您希望 sendn 字节在接收器上始终与 n 字节完全相同,每次。

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

    对于固定数据大小的协议(或任何可以预先预测下一个块大小的协议),您可以在流套接字上构建自己的“类似数据报的接收器”,只需在循环中 recv()ing,直到您准确获取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 代码;不一定高效;等等)。

    【讨论】:

      【解决方案3】:

      您可能不会假设数据可以从本地套接字读取,其大小与在另一个源端发送时提供的大小相同。正如您所看到的,这有时可能通常是正确的,但绝不是可靠的。相反,TCP 保证的是,在一端发生的事情最终会出现在另一端,以便没有任何遗漏 ,或者如果无法通过协议内置的方式(例如重试)来实现,那么整个事情就会中断错误

      Nagle 是一种可能的原因,但不是唯一的原因。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-03-31
        • 1970-01-01
        • 2017-06-05
        • 1970-01-01
        • 1970-01-01
        • 2015-02-07
        • 2014-11-20
        相关资源
        最近更新 更多