TCP 使用各种机制来检测数据包丢失并决定何时重新传输段。在这个问题中,我问的是基于超时的重传,其中 TCP 在某个计时器到期时重新传输某些段。这是一个单一的全局重传定时器,即重传队列中的所有段都有一个定时器,还是队列中的每个段都有一个独立的重传定时器?
具体来说,我认为可能的(互斥)选项是:
- 选项 A:有一个单一的全局计时器。
- 当一个段被发送时,如果定时器没有被激活,它就会被启动,并且该段的副本被放置在重传队列中。
- 当一个确认该特定段(可能在其他段中)的 ACK 到达时,它将从重传队列中删除。
- 每当任何ACK 到达时,无论它正在确认什么数据,重传计时器都会重置。
- 当计时器到期(在那个时间窗口内没有收到任何 ACK)时,在重传队列的前面重新传输一些(可能只是一个)段并重置计时器(可能具有更长的持续时间)。
- 当重传队列为空时,取消定时器。
- 选项B:重传队列中的每个段都有自己独立的定时器。
- 当一个段被发送时,一个副本被放置在重传队列中,一个新的重传定时器与之相关联,并且定时器被启动。
- 当一个确认该特定段(可能在其他段中)的 ACK 到达时,它将从队列中删除,并取消其关联的计时器。
- 当特定段的计时器到期时,重新传输该段并重置计时器。
我正在考虑可能是这种情况的其他选项,但它们是这两个选项的变体。
这就是我的困惑是如何产生的。首先,这个答案说:
根据 RFC 793,TCP 在其重传队列中的每个段使用一个重传计时器。
这支持选项 B。最近,在我正在学习的网络系统课程中,讲师以一种似乎暗示只有一个计时器的方式提到了这种机制(选项 A)。我问了他这个具体的问题,他确认只有一个计时器,并且收到任何 ACK 都会重置它。当然,这与我之前的想法相矛盾,因此我尝试自己访问主要资源以试图阐明这一点。RFC 793的原始版本在第 2.6 节中提到了以下内容(重点是我的):
当 TCP 传输包含数据的段时,它会将副本放入重传队列并启动计时器;当收到对该数据的确认时,将从队列中删除该段。如果在定时器用完之前没有收到确认,则重传该段。
此外,在同一文档的第 3.9 节中,在“RETRANSMISSION TIMEOUT”标题下,这样写:
对于任何状态,如果重传队列中某个段的重传超时到期,则再次发送重传队列前面的段,重新初始化重传计时器,然后返回。
就其措辞而言,它似乎在重传队列中为每个段指定一个独立的计时器(选项 B);虽然,老实说,这对我来说很模糊。
但是,最新版本的 RFC 793不包括第一个引用的段落(或任何等效的,据我所知),但第二个仍然存在。再一次,RFC 6298 的第 5 节内容如下:
5. 管理 RTO 定时器
实现必须以这样一种方式管理重传计时器,即一个段永远不会过早重传,即,在该段的先前传输之后少于一个 RTO。
以下是管理重传定时器的推荐算法:
(5.1) 每次发送包含数据的数据包(包括重传)时,如果定时器没有运行,则启动它运行,使其在 RTO 秒后到期(对于 RTO 的当前值)。
(5.2) 当所有未完成的数据都被确认后,关闭重传定时器。
(5.3) 当收到确认新数据的 ACK 时,重新启动重传计时器,使其在 RTO 秒后到期(对于 RTO 的当前值)。
当重传计时器到期时,请执行以下操作:
(5.4) 重传尚未被 TCP 接收方确认的最早段。
(5.5) 主机必须设置 RTO <- RTO * 2(“退出计时器”)。上面 (2.5) 中讨论的最大值可以用来为这个加倍操作提供一个上限。
(5.6) 启动重传定时器,使其在 RTO 秒后到期(对于 5.5 中概述的加倍操作后的 RTO 值)。
[...]
这显然指定了选项 A。但它说这只是推荐的算法,所以它可能不是“核心”TCP 标准的一部分?
我非常困惑。你能用权威的参考资料帮我解决这个问题吗?