【问题标题】:Windows Socket TCP Client Receives data only every 200ms (QTCPSocket)Windows Socket TCP 客户端仅每 200 毫秒接收一次数据 (QTCPSocket)
【发布时间】:2013-01-31 13:30:57
【问题描述】:

我正在使用QTCPSocket 连接到 TCP 服务器(在 Ubuntu 上运行)。服务器至少每 40 毫秒发送一个 1 字节的数据包。我的应用程序是实时的,因此以增加网络流量为代价尽可能快地接收数据非常重要。

从 Windows 连接 TCP 客户端后,我开始接收数据包。但是,来自QTCPSocketreadyRead() 信号仅每 200 毫秒发出一次(数据包中有 5 个字节)。我查看了 Wireshark 中的数据包,它们实际上是 5 字节的数据包。

但是,在 Mac 上使用QTCPSocket(实际上是完全相同的代码),我每次都会收到单独的数据包,我发送的所有 1 字节数据包都以单字节数据包的形式到达,这很棒。

我尝试创建一个原始 Windows 套接字(不使用 QTCPSocket),并在 Windows 上获得与 QTCPSocket 相同的行为。

导致 Mac 套接字以更高的时间分辨率接收数据包的区别是什么?我可以在setsockopt() 中设置什么来防止这 200 毫秒的缓冲发生吗?

我知道在服务器端设置 TCP_NODELAY 可能会解决我的问题,但是看到 Mac TCP 客户端按预期工作,必须有一种方法可以在 Windows 上获得相同的行为。

【问题讨论】:

  • 在服务器端设置 mySocket->setSocketOption(QAbstractSocket::LowDelayOption, 1); 是我发现解决此问题的唯一方法
  • 您尝试先修复协议?因为这一直对我有用。
  • TCP 是一种流协议。 UDP 可能更适合这种用途。
  • @Roku:不太可能,因为他必须自己处理重传、复制、传输节奏等。如果 TCP 做了一些您不需要的昂贵的事情,那么 UDP 是一个更好的选择。但如果你的想法是“我可以做 TCP 做的所有事情,但以某种方式做得更好”,那就算了。
  • 这取决于环境和可靠性要求。如果环境是一个低负载的局域网,并且如果应用程序每月丢失一个数据包不是致命的,那么UDP就足够了。当然,尝试在 UDP 之上构建自己的 TCP 是不明智的。您只需要了解这些协议的工作原理、您自己的要求并做出相应的选择。

标签: windows macos qt sockets tcp


【解决方案1】:

设置 mySocket->setSocketOption(QAbstractSocket::LowDelayOption, 1);在服务器端是我发现解决此问题的唯一方法

【讨论】:

    【解决方案2】:

    对于其他偶然发现来自搜索引擎的人:

    上述oggmonster的(正确)答案也可以这样描述:

    int on = 1;
    if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char*)&on, sizeof(on)))
      {
      return -1;
      }
    

    【讨论】:

      【解决方案3】:

      您需要确认收到的每个数据字节,以便回复 ACK 一些数据以供捎带。与设计您的协议的人交谈。

      仅当两种行为都不正确时,尝试回答“为什么它在 X 上而不在 Y 上有效”之类的问题才有用。如果它没有应用程序级别的确认,那么这两种行为都是正确的。如果其中一个不正确,那么协议应该有一种机制来控制它,例如应用层确认。如果不是,则协议已损坏。试图弄清楚为什么一个损坏的协议不起作用是没有意义的——它不起作用是因为它被损坏了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-29
        • 1970-01-01
        • 2016-03-31
        • 2016-09-15
        • 1970-01-01
        相关资源
        最近更新 更多