在 TCP 重传超时到期后,是否应该将所有发送的段重新排队?

网络工程 通讯协议 协议理论 传输协议 第4层 射频卡
2021-07-22 06:22:41

我正在开发 TCP 实现,但在相关 RFC(793、1122、5681、6298)中找不到对此的说明。当重传定时器超时时,重传已发送但尚未确认的第一个段,并将CWND设置为一个段。然后应该使用slow-start,对于每个新的ACK,它会将CWND增加一个段。

问题是其他已经发送的段是否被有效地重新排队以进行传输,就好像它们从未被发送过一样。特别地,假设收到了一个 ACK​​,它充分增加了 CWND 以允许发送剩余的已发送段之一,但不确认它。这样的段应该现在传输,还是只在下一次重传计时器到期时传输?

例子:

  • 第一次发送以下段(由它们的序列号表示):1000、2000、3000、4000。CWND(拥塞窗口)和 SND_WND(接收器窗口)都足够大,可以发送这些段。
  • 重传定时器在收到任何 ACK 之前到期。段 1000 被重传。慢启动开始,因此 CWND 减少到 1000 (=MSS)。
  • 收到 ACK num 2000,确认第一个但不确认任何其他段。根据慢启动算法,CWND 增加到 2000。
  • 此时,CWND 允许传输段 2000 和 3000。现在传输段 2000 和 3000,还是需要重新传输计时器的另一个到期才能传输段 2000?
2个回答

根据 RFC 793,TCP 对其重传队列中的每个段使用重传计时器。这意味着您示例中的段 2000 仅在其自己的重传计时器到期时才会重传。

当收到 ACK num 2000 时,CWND 允许 2000 个未完成的字节。但此时,还有 3000 字节未完成,所以没有额外发送。TCP 在重新发送段 2000、3000 和 4000 之前等待相应的重传计时器。

但是,在您的示例场景中,一次发送四个段,这意味着它们各自的重传计时器将(几乎完全相同)同时到期。这将导致在重传段 1000 之后立即重传段 2000 和 3000。

为了清楚地回答这个问题,RFC 793的TCP会不会“等待另一个到期重发定时器”,因为那里是“没有这样的事重传定时器”。TCP 将等待任何当前活动的重传定时器超时以重传相应的段。

实际上,TCP 自 1981 年以来一直在发展。

例如,快速重传 (RFC 2581/5681) 是上述规则的一个例外。在收到三个重复的 ack 指示一个段的无序接收后,快速重传将在它的重传计时器到期之前开始重传一个段。

TCP 是面向字节流的,重传队列保存之前发送的段只是实现重传的众多方式之一。

TCP 实现也可能没有这样的队列,并从缓冲区中第一个未确认的字节开始生成一个新段。没有规范要求这是先前发送的段的精确副本。它可能具有不同的大小或包含字节流的部分重叠部分。

引入诸如选择性确认之类的功能使事情变得更加复杂。

在您的示例中,“现在”传输 2000 和 3000。重传计时器仅用于指示丢失数据包的可能性,一旦开始重传,您就“已经这样做了”。