(在该问题被认为偏离 Stack Overflow 和网络工程主题后,尝试了这个论坛)
我正在调查一个问题,我们在一个简单的 tcp 客户端/服务器应用程序中偶尔看到 200ms 以上的峰值。这些峰值始终在 200ms - 220ms 范围内,表明在这种情况下正在使用基于 RTO 的重传。例如,这是来自 tcpdump 的一个示例:
1. 2022-08-30 05:42:12.354834 Client > Server: Flags [P.], cksum 0x3aa4 (incorrect -> 0xbd21), seq 1337931499:1337964267, ack 71199642, win 54, options [nop,nop,TS val 3783770243 ecr 1428361383], length 32768
2. 2022-08-30 05:42:12.358580 Client > Server: Flags [P.], cksum 0xd09b (incorrect -> 0x3c8b), seq 1337958643:1337964267, ack 71199642, win 54, options [nop,nop,TS val 3783770247 ecr 1428361383], length 5624
3. 2022-08-30 05:42:12.358615 Server > Client: Flags [.], cksum 0x8759 (correct), ack 1337931499, win 986, options [nop,nop,TS val 1428361888 ecr 3783769742,nop,nop,sack 1 {1337958643:1337964267}], length 0
# 200ms wait here
4. 2022-08-30 05:42:12.563601 Client > Server: Flags [.], cksum 0xddfb (incorrect -> 0xce54), seq 1337931499:1337940547, ack 71199642, win 54, options [nop,nop,TS val 3783770452 ecr 1428361888], length 9048
- 客户端向服务器发送一个 32KB 的请求。我们的 MTU 配置为 9100。
- 客户端在接下来的 3 毫秒内未收到来自服务器的任何确认。因此,某种早期重传逻辑开始发挥作用。客户端重传最后一个段(最后 5624 个字节)。
- 服务器发回一个确认,表示已收到这 5624 个字节(
sack 1 {1337958643:1337964267}
)。总体确认数未按预期增加。 - 客户端等待 200 毫秒以上才重新传输其他段。
这只是一个例子。还有其他情况,例如,在客户端发送 32KB 请求后,服务器发回一个确认,表示只收到了 3 个段。因此,客户端重新传输最后一个段,但后等待200毫秒。
我的问题是 - 为什么客户端要等待 200ms 才重新传输丢失的段,即使服务器已经为收到的段发送了确认?为什么它不在收到服务器的确认后立即重新传输,或者采用其他快速重新传输机制?
win
这与服务器确认中的窗口长度(步骤3中的986)有关吗?
任何见解均值得赞赏!