【问题标题】:ACK & TCP Window on UbuntuUbuntu 上的 ACK 和 TCP 窗口
【发布时间】:2016-07-22 05:37:57
【问题描述】:

晚上好,

我正在开发一个项目,该项目在 Python 中使用 wsgi 之上的 eventlet http://eventlet.net/ 来创建 websocket 服务器。到目前为止,一切都运行良好。然而,我们今天做了一些深度数据包分析,发现了一些奇怪的东西。我们正在尝试最小化来自服务器的出站数据。目前,它似乎只发送 ACK,这会占用目前出站的大部分数据(大约每小时 1M)。

无论我们在 Ubuntu sysctl 文件上设置什么接收窗口,都会同时向客户端发送一个 ACK​​(在 5 个数据包之后)。我们想让这个窗口更大,这样每 15 个数据包可能会发送 1 个 ACK​​,这些数据包的大小为 1440 字节

以下是我们对 TCP 发送和接收缓冲区的 sysctl 设置

net.core.wmem_max = 4194304
net.core.rmem_max = 6291456
net.ipv4.tcp_rmem = 4096 2097152 6291456
net.ipv4.tcp_wmem = 4096 1048576 4194304
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_sack = 1
net.core.netdev_max_backlog = 5000

正如您将看到的那样,我们启用了缩放,启用它后,服务器在其 Ack 中设置 Win=8159,但是即使禁用它并且在服务器 ACK 窗口中发送默认值 64k,ACK 实际上正在被发送回每 7k 左右发给客户一次。

我们这里缺少一些基本的东西吗?客户端是否可以设置缓冲区限制,除非收到 ACK,否则它将不再发送数据?无论接收到的缓冲区大小如何,发送 ACK 是否有某种时间限制?

感谢您的帮助。

【问题讨论】:

    标签: python sockets ubuntu networking tcp


    【解决方案1】:

    无论接收到的缓冲区大小如何,发送 ACK 是否有某种时间限制?

    发送ACK是为了给接收者一个反馈,如果发送者在一段时间内(估计的RTT)没有收到ACK,它会猜测数据包丢失并重新发送这个数据包。在基本的 tcp 版本中,将发送 ACK 以响应每个数据包,但作为优化,许多操作系统实现了延迟 ACK。接收方在发送 ACK 之前会等待一段时间,如果接收方在此超时期间接收到另一个数据包,它将只为在此期间接收到的那些数据包生成一个 ACK​​(最大数量)。因为这个 ACK​​ 将被发送而不管任何接收缓冲区。在 linux 上,您可以通过TCP_QUICKACK 套接字选项禁用延迟 ACK,在这种情况下,每个接收到的数据包都会生成 ACK 数据包。在某些版本的 linux 上,您还可以更改此超时,但这可能会导致不必要的数据重传。

    客户端能否设置缓冲区限制,除非收到 ACK,否则它将不再发送数据?

    可以通过更改发送缓冲区来实现。如果发送缓冲区已满,则下一个写入操作将阻塞(在阻塞客户端的情况下)。每个 ACK​​ 都会从发送缓冲区中释放数据包并允许下一次写入操作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-26
      • 1970-01-01
      • 1970-01-01
      • 2012-07-18
      相关资源
      最近更新 更多