为了形成正确的 SACK 编号,TCP 使用哪种数据结构来跟踪接收和丢失的字节?

为了形成正确的 SACK 编号,TCP 使用哪种数据结构来跟踪接收和丢失的字节?

假设我有一个客户端成功接收了来自服务器的以下字节范围内的数据包:0-99、100-199、200-299。下一个数据包 300-399 丢失,但最后一个数据包 400-499 成功接收。

当客户端解析数据包 400-499 时,它意识到前一个段 300-399 丢失了。

这是一个简化的示例,可以通过以下方法解决:

  • 1 个数字跟踪按顺序读取的数据,
  • 另一个数字是下一个预期的按顺序数据,
  • 第三个数字将跟踪第一个较大的无序数字,并且
  • 第四,最后一个最大的无序数。

我认为这种方法适用于所有丢失的数据包都是连续的,并且 TCP 流中只有 1 个间隙的情况。什么样的数据结构可以跟踪不连续的丢失数据包的多个片段?这在操作系统级别是如何实现的?这将有助于我理解 SACK 实现。SACK 最多可以有 4 个块,并且它用“NOP”预先填充每个块,直到 TCP 选项中最多能被 4 整除的字节数。我还没有看到过有超过 1 个 SACK 选项的 pcap。

我的问题是关于底层技术如何跟踪构建 SACK 所需的数字,而不是 SACK 本身的实现。

答案1

这个机制其实非常简单。

维基百科传输控制协议 (TCP) 说:

基于 Dupack 的重传

如果流中的一个段(例如段号 100)丢失,则接收方无法确认该段号(100)以上的数据包,因为它使用累积 ACK。因此,接收方在收到另一个数据包时再次确认数据包 99。此重复确认用作数据包丢失的信号也就是说,如果发送方收到三个重复确认,它将重新传输最后一个未确认的数据包。之所以使用阈值 3,是因为网络可能会重新排序段,从而导致重复确认。此阈值已被证明可以避免由于重新排序而导致的虚假重新传输。一些 TCP 实现使用选择性确认 (SACK) 来提供有关已收到段的明确反馈。这极大地提高了 TCP 重新传输正确段的能力。

如果重新排序超出了重复确认阈值,则重传模糊性可能会导致虚假的快速重传和拥塞避免。

相关内容