TCP 确认暂停,然后恢复,然后再次暂停。为什么?

mar*_*ans 6 linux tcp wireshark

我需要一些帮助来找出我的应用程序中数据传输率降低的原因。

我有 12 个嵌入式系统和一个 Linux 服务器。嵌入式系统通过交换机通过以太网链路上的 TCP 向服务器发送数据。下面是一个 TCP StreamGraph,它是由 Wireshark 从一块板上捕获的流量制成的。

TCP 流图

如您所见,数据传输速度约为 5.8MBit/s,最长约为 0.25 秒。这与我期望嵌入式系统运行的速度一样快。在此之后,传输中会插入延迟。下图显示了该图的特写:

缩放流图

底部标记为 ACK 的阶梯状曲线显示在任何给定时间服务器已确认的数据量。标有 RWIN 的相应曲线显示了 datapc 上的缓冲区中有多少空间。标记为 SENT DATA 的较小垂直段是实际发送的数据包。

在 A 点,服务器以与发送数据一样快的速度确认数据,但在 23 毫秒的持续时间内,服务器没有发送任何确认数据。嵌入式系统被允许在不等待 ACK 的情况下发送到 RWIN,但它不会这样做,因为它需要保留发送的数据直到它们被确认(以防它们需要重新传输)并且发送缓冲区空间是有限的。

然后,在 B 点,所有接收到的数据立即被确认,正常确认和发送恢复 2.5 毫秒,然后再发生暂停。

Wireshark 捕获是从连接到交换机上的端口的不同 PC 进行的,该端口设置为镜像在嵌入式系统所连接的端口上发送和接收的所有数据。

Linux 服务器运行 Java 应用程序,该应用程序处理数据并将其存储在磁盘上。它没有显示 CPU 已用尽的迹象。操作系统是具有默认网络设置的 Ubuntu Server 12.04。

我可以看到,在嵌入式系统中分配更多的发送缓冲区空间以匹配 Linux 服务器中的接收窗口空间量可能会使我受益,但这似乎不是这里的限制因素。

我的问题是:

  1. 尽管 Linux 服务器显然能够很好地接收所有内容,但它暂停 ACK 的原因可能是什么?
  2. 我该如何去调试这个?

小智 0

另一个明显的问题是为什么客户端停止发送?通常客户端在发送下一个 TCP 数据包之前不会停下来等待 ACK。他们是否可能发送被内格尔算法延迟的单字节消息?

https://en.wikipedia.org/wiki/Nagle%27s_algorithm

如果是,并且您的 Linux 服务器正在使用 TCP 延迟确认,那么您预计 ACK 延迟将高达 500 毫秒。

https://en.wikipedia.org/wiki/TCP_delayed_acknowledgment

如果是这种情况,那么可以通过使用更大的消息或在嵌入式系统上禁用 Nagle 算法 (TCP_NODELAY) 轻松修复。