【问题标题】:Lowest TCP receive window size最小 TCP 接收窗口大小
【发布时间】:2019-03-22 12:40:38
【问题描述】:

Linux 内核 TCP/IP 堆栈 impl 可以宣布的最小 TCP 接收窗口大小是多少,我如何配置以使其宣布这样一个?我的目标是实现低延迟并牺牲吞吐量?

【问题讨论】:

  • 为什么您认为减小 TCP 接收窗口大小会降低延迟?
  • 为了低延迟,您应该使用带有内核绕过的 UDP。
  • "为了低延迟,您应该使用带有内核绕过的 UDP" - 此时服务器只接受 TCP 连接。 “为什么你认为减小 TCP 接收窗口大小会减少延迟?” - 现在我的测试客户端应用程序每秒从缓冲区读取大约 128 个字节,TCP 堆栈等待直到有可用的 SO_RCVBUF/2 字节空间,然后通知服务器新窗口大小。如果可能的话,我想让我的客户宣布窗口大小低于 SO_RCVBUF/2。

标签: sockets tcp network-programming


【解决方案1】:

现在我的测试客户端应用程序每秒从缓冲区读取大约 128 个字节,并且 TCP 堆栈等待直到有可用的 SO_RCVBUF/2 字节空间,然后才通知服务器有关新窗口大小的信息。如果可能的话,我想让我的客户宣布窗口大小低于 SO_RCVBUF/2。

我认为更改接收窗口大小不会对延迟产生任何影响。

但是,由于您的消息很小(128 字节),您可能希望在发送方中禁用Nagle algorithm,这会使发送方在发送小于 MSS 的 TCP 有效负载时等待:

期望实时响应和低延迟的应用程序对 Nagle 算法的反应可能很差。网络多人视频游戏或远程控制操作系统中的鼠标移动等应用程序期望立即发送操作,而算法有目的地延迟传输,以牺牲延迟为代价提高带宽效率。出于这个原因,具有低带宽时间敏感传输的应用程序通常使用TCP_NODELAY 来绕过 Nagle 延迟。

您可能希望在接收器上禁用TCP delayed acknowledgements

延迟的 ACK 引入的额外等待时间可能会在与某些应用程序和配置交互时导致进一步的延迟。如果发送方正在使用 Nagle 算法,则数据将由发送方排队,直到收到 ACK。如果发送方没有发送足够的数据来填充最大段大小(例如,如果它执行两次小写入,然后是阻塞读取),则传输将暂停,直到 ACK 延迟超时。 Linux 2.4.4+ 支持TCP_QUICKACK 套接字选项,可禁用延迟 ACK。

C++ 代码:

void disableTcpNagle(int sock) {
    int value = 1;
    if(::setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &value, sizeof value)) 
        throw std::system_error(errno, std::system_category(), "setsockopt(TCP_NODELAY)");
}

void enableTcpQuickAck(int sock) {
    int value = 1;
    if(::setsockopt(sock, IPPROTO_TCP, TCP_QUICKACK, &value, sizeof value)) 
        throw std::system_error(errno, std::system_category(), "setsockopt(TCP_QUICKACK)");
}

【讨论】:

  • 我同意你的评论,但问题是我无法访问服务器,我想知道在技术上是否有可能在客户端强制内核宣布较低的 TCP 窗口。跨度>
  • @hwasin 为您添加了TCP_QUICKACK 注释。
  • 谢谢。我尝试了这个选项,但接收器窗口大小仍然没有减小。请看this question
  • @hwasin TCP_QUICKACK 与接收者窗口大小无关。接收窗口大小由SO_RCVBUF 套接字选项控制。
  • 但是如果启用了 TCP_QUICKACK 选项,因此我的 128 字节 ACKnowledgment 应该被传送到服务器,那么客户端也应该宣布 128 字节接收器窗口,但内核不这样做,它等到 SO_RCVBUF/2 窗口大小可以公布。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-05
  • 1970-01-01
  • 1970-01-01
  • 2011-07-09
  • 1970-01-01
  • 2013-01-01
相关资源
最近更新 更多