下面的tcpdump日志是从我最近运行的测试中复制的。一开始一切都很顺利。然后客户端最终淹没了路由器,然后很多数据包[# - 6176]被丢弃(永远不会看到它们的ACK)。然后在6177,由于τ定时器超时而触发重新发送。
以下是问题:
- 当有重新传输时,发送方侧拥塞窗口(snd_cwnd)会发生什么? os是linux内核3.4.42。如上所述,当重新传输时,snd_cwnd将减少到1。如果是这种情况,为什么仍然可以发送数据包6179,6180?
- 为什么6179,6180没有得到确认?相反,6178可以得到确认,意味着数据包可以通过。
醇>
6174 2.881075 10.203.85.190 207.198.102.53 TCP 1426 58206 > 80 [ACK] Seq=6379071 Ack=1 Win=13824 Len=1358 TSval=4294945643 TSecr=2532115493
6175 2.881094 10.203.85.190 207.198.102.53 TCP 1426 58206 > 80 [ACK] Seq=6380429 Ack=1 Win=13824 Len=1358 TSval=4294945643 TSecr=2532115493
6176 2.881114 10.203.85.190 207.198.102.53 TCP 1426 58206 > 80 [ACK] Seq=6381787 Ack=1 Win=13824 Len=1358 TSval=4294945643 TSecr=2532115493
6177 3.227347 10.203.85.190 207.198.102.53 TCP 1426 [TCP Retransmission] 58206 > 80 [ACK] Seq=5887475 Ack=1 Win=13824 Len=1358 TSval=4294945685 TSecr=2532115493
6178 3.323055 207.198.102.53 10.203.85.190 TCP 68 http > 58206 [ACK] Seq=1 Ack=5888833 Win=980480 Len=0 TSval=2532115623 TSecr=4294945685
6179 3.326368 10.203.85.190 207.198.102.53 TCP 1426 58206 > 80 [ACK] Seq=6383145 Ack=1 Win=13824 Len=1358 TSval=4294945694 TSecr=2532115623
6180 3.326454 10.203.85.190 207.198.102.53 TCP 1426 58206 > 80 [ACK] Seq=6384503 Ack=1 Win=13824 Len=1358 TSval=4294945694 TSecr=2532115623
6181 3.727429 10.203.85.190 207.198.102.53 TCP 1426 [TCP Retransmission] 58206 > 80 [ACK] Seq=5888833 Ack=1 Win=13824 Len=1358 TSval=4294945735 TSecr=2532115623
6182 3.813101 207.198.102.53 10.203.85.190 TCP 68 80 > 58206 [ACK] Seq=1 Ack=5890191 Win=980480 Len=0 TSval=2532115746 TSecr=4294945735
6183 3.813606 10.203.85.190 207.198.102.53 TCP 1426 58206 > 80 [ACK] Seq=6385861 Ack=1 Win=13824 Len=1358 TSval=4294945743 TSecr=2532115746
6184 3.813822 10.203.85.190 207.198.102.53 TCP 1426 58206 > 80 [ACK] Seq=6387219 Ack=1 Win=13824 Len=1358 TSval=4294945743 TSecr=2532115746
6185 4.197341 10.203.85.190 207.198.102.53 TCP 1426 [TCP Retransmission] 58206 > 80 [ACK] Seq=5890191 Ack=1 Win=13824 Len=1358 TSval=4294945782 TSecr=2532115746
6186 4.294162 207.198.102.53 10.203.85.190 TCP 68 80 > 58206 [ACK] Seq=1 Ack=5891549 Win=980480 Len=0 TSval=2532115866 TSecr=4294945782
6187 4.297450 10.203.85.190 207.198.102.53 TCP 1426 58206 > 80 [ACK] Seq=6388577 Ack=1 Win=13824 Len=1358 TSval=4294945792 TSecr=2532115866
6188 4.297675 10.203.85.190 207.198.102.53 TCP 1426 58206 > 80 [ACK] Seq=6389935 Ack=1 Win=13824 Len=1358 TSval=4294945792 TSecr=2532115866
答案 0 :(得分:0)
当您发送TCP数据包时,将创建一个重新传输计时器(对于每个数据包);如果在定时器到期时ACK没有出现,则重传该分组。此过程将多次发生(特定于操作系统且可配置),如果所有尝试都不成功,则连接将失败。 有关Linux中TCP / IP实现的更多信息,我强烈建议您参考:
Understanding Linux Network Internals
有关TCP的更多信息,请参阅:
答案 1 :(得分:0)
这与F-RTO有关,见rfc 5682.
在传统算法(非F-RTO)中,完成如下:
当发生重传超时时,TCP发送方进入RTO恢复,其中拥塞窗口初始化为一个段,未使用慢启动算法重新发送未确认的段。
以下是F-RTO的运作方式:
当重传定时器到期时,F-RTO发送方照常重传第一个未确认的分段。在超时后偏离正常操作,它会尝试传输新的,先前未发送的数据(通常是两段,如果有足够的数据和拥塞窗口允许),用于在超时后到达的第一个确认,假定确认推进了窗口。
所以这解释了为什么发送了6179和6180。为什么没有收到他们的ACK,我认为这是一些系统级错误,需要解决。