TCP报文故障时,为什么要重传整个缓冲区?

网络工程 通讯协议
2021-08-01 18:38:30

好吧,我对 TCP 的理解基本上是这样的:

我将这些数据分解成[#1,#2,#3,...]我想发送给 Bob 的数据包这些数据包已被包装,因此消息编号实际上包含在数据包中。所以我#1,#2,#3,...一一发送了Bob 确认的一些延迟。

在某些时候,我已将数据包发送#n#n+m,但 Bob 检测到数据包有错误#n他现在给我发了一条消息:“备份并转发n和转发”。收到此消息后,假设我已经传输了一个额外的p数据包。

m+p现在在以太坊中的这些数据包会发生什么据我了解,鲍勃丢弃它们?他为什么不只留下一个缓冲槽n,继续接收其他人?

发件人的相同问题 - 重新传输所有m+p+1数据包而不是仅传输数据包的原因是什么#n

2个回答

对于会话的每个方向,TCP 会跟踪发送的字节数和接收的字节数。这是使用序列号(跟踪发送的字节)和确认号(跟踪接收的字节)完成的。

为简单起见,我将继续处理,就好像 SEQ# 和 ACK# 是发送数据包计数(实际上,它是发送字节计数)。此外,我们只会跟踪一个方向的对话,我们不会打扰另一个方向的对话。

Bob                                 Alice
Sends packets #1, #2, #3 --->

Bob 向 Alice 发送带有 SEQ# 1、2 和 3 的数据包.... Alice 可以如何响应有以下三种可能性:

  • 如果 Alice 收到每个数据包,她将回复 ACK#4,表示她已经收到了 #4 之前的所有数据,并准备好接下来的 #4。

  • 如果 Alice 只收到#1,没有其他任何东西,她将用 ACK#2 响应,表明她已准备好接收#2,并且之前已经收到了所有信息。这将提示 Bob 再次发送 #2 和 #3。

  • 如果 Alice 只收到 #1 和 #3,并且不知何故 #2 在传输过程中丢失了。Alice 仍然别无选择,只能用 ACK#2 响应。请记住,Alice 只能用一个确认号码来响应,以确认她收到的数据包。如果她回复 #4,它会通知 Bob 收到了 #1、#2 和 #3,但事实并非如此。

因此,在这两种情况下之前,Bob收到ACK#2,和Bob没有办法知道是否方式只是#2或#2#3丢失了-所以为了安全起见,鲍勃将重新发送#2,#3。

也就是说,在上面的第 3 种情况下,当 Bob 重新发送 #2 和 #3,但 Alice 已经有了 #3..简单地忽略接收到的重复 #3 完全取决于实现——并且在很大程度上,用户不会注意到差异。最终效果是一样的。


当然,这只是因为只有两个数字被跟踪,一个 SEQ# 表示发送的字节,一个 ACK​​# 跟踪接收的字节。正如 OP 所指出的,TCP 添加了一项名为 Selective Acknowledgement 或TCP SACK 的功能

TCP SACK 允许接收方不仅发送 ACK#(接收到的字节数),而且还指定接收到的字节的“左边缘”和“右边缘”。然后向发送方具体指示哪些字节需要重新发送。

首先,网络中的一个重要概念是带宽和延迟的乘积。这决定了有多少数据包需要一次“飞行”才能充分利用。总的来说,随着带宽大幅增加而延迟大致保持不变(讨厌的光速限制),这个数字多年来一直在增长

传统上 TCP 只确认连续接收的数据。我不确定为什么要这样做,但我猜想简单是驱动力。

这让发件人有两个选择。它可以重新发送单个数据包并等待接收方的响应,也可以重新发送一堆数据包并可能最终发送重复数据。

我希望在早期的互联网中这不是什么大问题。带宽延迟产品相对较小,为每个丢失的数据包等待一个往返时间可能没什么大不了的。

随着带宽的增加,这成为一个更大的问题,经过 80 年代末和 90 年代初的实验,TCP 共享确认在 1996 年的 RFC2018 中标准化。