linux - TCP ACK 响应延迟 10ms

标签 linux networking tcp delay throughput

我正在编写一个应该从服务器接收文件的客户端应用程序。通信使用基于 TCP 设计的非常简单的专有协议(protocol):服务器发送一个 16KB 的数据 block ,等待来 self 的客户端的简单响应,然后继续下一个数据 block ;这样做直到文件被完全传输。

服务器在 Windows 上运行。如果我在 Windows 上运行我的客户端(通过 Cygwin),我可以达到 70Mbits/s 的吞吐量。但是,如果我在 Linux 上运行它,我可以获得的最大吞吐量是 5Mbits/s(两个测试都使用相同的 100Mb 以太网链路)。

在对我收集的 tcpdump 跟踪进行一些调查后,我发现 Linux 大约需要 10 毫秒来回答每个 TCP ACK。每次调用 recv() 后,我都尝试禁用 sockoption TCP_QUICKACK,但没有成功。我还没有找到任何其他可以改变这种行为的 TCP 选项(在 bsd 套接字下,甚至在 Linux 下)。

谁能帮我弄清楚发生了什么?

  1. 我的客户端是用 C++ 编写的,使用 BSD 套接字。 TCP_NODELAY 套接字选项已设置。
  2. 我的 linux 内核是 2.6.19
  3. 专有协议(protocol)和服务器不是我的,所以我无法以任何方式更改它们。

下面是我分析的 tcpdump 跟踪示例。这是 block 传输。服务器IP为10.200.252.1,客户端为10.200.252.2。以**开头的行是延迟10ms的TCP ACK数据包:

   5184 28.060969   10.200.252.1          10.200.252.2          TCP      1510   search-agent > 58358 [ACK] Seq=4736738 Ack=1741 Win=66048 Len=1444 TSval=2951472 TSecr=2921060
   5185 28.060978   10.200.252.1          10.200.252.2          TCP      1510   search-agent > 58358 [ACK] Seq=4738182 Ack=1741 Win=66048 Len=1444 TSval=2951472 TSecr=2921060
   5186 28.060981   10.200.252.1          10.200.252.2          TCP      1510   search-agent > 58358 [ACK] Seq=4739626 Ack=1741 Win=66048 Len=1444 TSval=2951472 TSecr=2921060
   5187 28.060987   10.200.252.1          10.200.252.2          TCP      1510   search-agent > 58358 [ACK] Seq=4741070 Ack=1741 Win=66048 Len=1444 TSval=2951472 TSecr=2921060
   5188 28.060990   10.200.252.1          10.200.252.2          TCP      1510   search-agent > 58358 [ACK] Seq=4742514 Ack=1741 Win=66048 Len=1444 TSval=2951472 TSecr=2921060
   5189 28.060994   10.200.252.1          10.200.252.2          TCP      1510   search-agent > 58358 [ACK] Seq=4743958 Ack=1741 Win=66048 Len=1444 TSval=2951472 TSecr=2921060
   5190 28.060997   10.200.252.1          10.200.252.2          TCP      1510   search-agent > 58358 [ACK] Seq=4745402 Ack=1741 Win=66048 Len=1444 TSval=2951472 TSecr=2921060
   5191 28.061000   10.200.252.1          10.200.252.2          TCP      1510   search-agent > 58358 [ACK] Seq=4746846 Ack=1741 Win=66048 Len=1444 TSval=2951472 TSecr=2921060
   5192 28.061003   10.200.252.1          10.200.252.2          TCP      1510   search-agent > 58358 [ACK] Seq=4748290 Ack=1741 Win=66048 Len=1444 TSval=2951472 TSecr=2921060
   5193 28.061007   10.200.252.1          10.200.252.2          TCP      1510   search-agent > 58358 [ACK] Seq=4749734 Ack=1741 Win=66048 Len=1444 TSval=2951472 TSecr=2921060
   5194 28.061038   10.200.252.1          10.200.252.2          TCP      1510   search-agent > 58358 [ACK] Seq=4751178 Ack=1741 Win=66048 Len=1444 TSval=2951472 TSecr=2921060
   5195 28.061042   10.200.252.1          10.200.252.2          TCP      572    search-agent > 58358 [PSH, ACK] Seq=4752622 Ack=1741 Win=66048 Len=506 TSval=2951472 TSecr=2921060
 **5196 28.068422   10.200.252.2          10.200.252.1          TCP      66     58358 > search-agent [ACK] Seq=1741 Ack=4742514 Win=64512 Len=0 TSval=2921061 TSecr=2951472
 **5197 28.078479   10.200.252.2          10.200.252.1          TCP      66     58358 > search-agent [ACK] Seq=1741 Ack=4753128 Win=64512 Len=0 TSval=2921062 TSecr=2951472
   5198 28.082418   10.200.252.2          10.200.252.1          TCP      70     58358 > search-agent [PSH, ACK] Seq=1741 Ack=4753128 Win=64512 Len=4 TSval=2921062 TSecr=2951472
   5199 28.082675   10.200.252.2          10.200.252.1          TCP      68     58358 > search-agent [PSH, ACK] Seq=1745 Ack=4753128 Win=64512 Len=2 TSval=2921062 TSecr=2951472
   5200 28.082714   10.200.252.1          10.200.252.2          TCP      66     search-agent > 58358 [ACK] Seq=4753128 Ack=1747 Win=66048 Len=0 TSval=2951474 

最佳答案

完全摆脱分 block 和应用程序 ACK。如果必须的话,在文件末尾放最后一个。 TCP 已经进行了分 block 和 ACK,你正在把它逼疯,例如它必须对 ACK 进行 ACK。不需要所有这些复杂性。这是一种流式传输协议(protocol):像使用它一样使用它。

关于linux - TCP ACK 响应延迟 10ms,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17845000/

相关文章:

c# - 我无法通过互联网连接到服务器

c++ - 解析/etc/network/interfaces

python - 使用 TCP 连接发送 PNG 文件

c++ - 场景刷新卡住

c - 使用ftw库进行linux c编译

Linux/中央操作系统 : How to force FTP/SSH to use a particular ethernet adapter

linux - 如何正确计算TCP数据包校验和?

linux - 我可以为单个应用程序禁用 TCP 窗口缩放吗?

php - 为什么 PHP 卡在 mysqli_connect 而没有错误代码?

linux - 树莓派 : make command not working with below makefile