TCP New Reno 是什么?
TCP New Reno 是 TCP Reno 的扩展。它克服了 Reno 的局限性。 TCP Reno 是 TCP 的第二个变体,它提出了一个内置的拥塞算法。拥塞处理不是原始 TCP/IP 套件的组成部分。 TCP Reno 是 TCP Tahoe 的扩展,NewReno 是 TCP Reno 的扩展。在 Reno 中,当丢包发生时,发送方将 cwnd 连同 ssthresh 值一起减少 50%。这将允许网络轻松摆脱拥塞状态。但 Reno 遭遇了非常严重的积压,这影响了它的表现。
当在同一个拥塞窗口(例如 1-10)中丢弃多个数据包时,每次它知道有数据包丢失时,它都会将 cwnd 减少 50%。因此,对于 2 个丢包,它将 cwnd 减少 4 倍(50% 两次)。但是,每个拥塞窗口减少 50% 就足以恢复所有丢失的数据包。说cwnd=1024,在这个窗口丢了10个包,Reno会10倍减少cwnd 50%,最后cwnd=1024/2 10 = 1,很惊人。发送方需要 10 个 RTT 才能再次使用慢启动将其 cwnd 增加到 1024,不考虑 AIMD 算法。
雷诺的局限性:
- 在同一个拥塞窗口中检测多个丢包需要花费大量时间。
- 对于同一窗口中的多个数据包丢失,它会多次减少拥塞窗口,其中一次减少就足够了。
新里诺是如何进化的?
这个想法是为了克服 Reno 的局限性。诀窍是让发送方知道对于在同一拥塞窗口中发生的所有数据包丢失,它需要将 cwnd 减少 50%。这是使用部分 ACK 完成的。引入了新型 ACK 来让发送者知道这一点。在 Reno 中,当它接收到重传数据包的 ACK 时,经过半个静默窗口后,它认为这是一个新的 ACK,并快速恢复并进入 AIMD,然后如果发生丢包(相同的 cwnd),它会重复相同的减少 cwnd 的过程减半。但是 NewReno 发送方将检查重传数据包的 ACK 是否是新的,即该特定 cwnd 的所有数据包是否都被接收方确认。如果接收方确认了该特定 cwnd 的所有数据包,则发送方将认为该 ACK 为新的否则为部分 ACK。如果是部分 ACK,那么发送方不会再将 cwnd 减少 50%。它将保持相同,并且不会退出快速恢复阶段。
NewReno 解决方案:
它使用部分确认的概念。当发送方收到第一个重传数据包的 ACK 时,它不像 TCP Reno 那样将其视为“新 ACK”。 NewReno 检查该特定窗口的所有先前传输的数据包是否都被确认。如果在同一个拥塞窗口中丢失了多个数据包,那么即使在接收到重传数据包之后,接收方也只会发送重复的 ACK。这将使发送方清楚所有数据包都没有到达接收方,因此发送方不会认为该 ACK 是新的。它将认为它是部分 ACK,因为只有部分窗口被确认,而不是整个窗口。 Reno 曾经在收到新的 ACK 后退出快速恢复阶段,但 NewReno 认为该 ACK 是局部的,并没有退出快速恢复阶段。当它接收到整个拥塞窗口的累积 ACK 时,它明智地做出结束快速恢复阶段的决定。
因此,NewReno 会立即检测到多个数据包丢失,并且不会像 Reno 那样过早退出快速恢复阶段。
用一个例子来理解:
假设:
- 发件人有无限数据要发送
- initcwnd = 10 段
- 数据包 3 和 4 被丢弃。
S.No. | Packets ACKed | cwnd | inflight | Packets transmitted |
---|---|---|---|---|
1. | None | 10 | 10 | 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 |
2. | 1 | 11 | 11 | 11, 12 |
3. | 2 | 12 | 12 | 13, 14 |
4. | 2(DA1, R5) | 13 | 13 | 15, 16 |
5. | 2(DA2, R6) | 14 | 14 | 17, 18 |
6. | 2(DA3, R7) * | 7 | 13 | Re 3 |
7. | 2(DA4, R8) | 7 | 12 | – |
8. | 2(DA5, R9) | 7 | 11 | – |
9. | 2(DA6, R10) | 7 | 10 | – |
10. | 2(DA7, R11) | 7 | 9 | – |
11. | 2(DA8, R12) | 7 | 8 | – |
12. | 2(DA9, R13) | 7 | 7 | – |
13. | 2(DA10, R14) | 7 | 7 | 19 |
14. | 2(DA11, R15) | 7 | 7 | 20 |
15. | 2(DA12, R16) | 7 | 7 | 21 |
16. | 2(DA13, R17) | 7 | 7 | 22 |
17. | 2(DA14, R18) | 23 | ||
18. | 3 | 7 | 7 | 24 |
19. | 3(DA1, R19) | 7 | 7 | 25 |
20. | 3(DA2, R20) | 7 | 7 | 26 |
21. | 3(DA3, R21)* | 7 | 7 | Re 4 |
22. | 3(DA4, R22) | 7 | 7 | 27 |
23. | 3(DA5, R23) | 7 | 7 | 28 |
24. | 3(DA6, R24) | 7 | 7 | 29 |
25. | 3(DA7, R25) | 7 | 7 | 30 |
26. | 3(DA8, R26) | 7 | 7 | 32 |
27. | 26 | (7+1/7) | 7 | 32 |
步骤 18 到 20 :TCP Reno 认为它是一个新的 ACK,从快速恢复阶段出来,进入 AI 阶段。而 NewReno 将其标记为部分 ACK 并持续处于快速恢复阶段。发送方检查它是否已收到此特定拥塞窗口的所有数据包的所有 ACK。如果是,那么这是一个新的 ACK,否则是部分 ACK。
第 21 步:从 18-20,TCP Reno 将每个 ACK 的拥塞窗口增加 1/7。但是NewReno保持cwnd=inflight=7,因为它还处于Fast Recovery阶段,还没有进入AI阶段。它在收到 3 个重复的 ACK 后重新传输数据包 4。
步骤 22 到 26:发送方得到重复的 ACK 并保持 cwnd=inflight。它根据 ACK 向链路发送一个新数据包。快速恢复阶段尚未结束。因为它没有收到新的ACK。
步骤27 :接收方收到发送方重传的packet-4。现在,接收者按顺序拥有了从 1 到 26 的所有数据包。丢失的数据包 3 和 4 也被接收器接收,因此现在它发送数据包 4-26 的累积 ACK 作为 ACK-26。直到最后一步,它都在发送重复的 ACK-3,表示它已按顺序接收到数据包 3。发送方现在收到累积的 ACK 并检查它是否是新的 ACK。
ACK received > cwnd ? Yes : No
26 > 10 ? yes : No
因此,是的,ACK-26 是一个新的 ACK。因此,现在发送方将退出快速恢复阶段。
请注意,与 Reno 相比,发送方在快速恢复阶段停留的时间更长,但它并没有针对同一个拥塞窗口多次降低 cwnd 和 ssthresh。这在 TCP Reno 中不可用。