TCP重传机制

 

基于超时的重传

原理

发送方发送数据包后,启动一个计时器 (重传定时器),重传间隔为RTO(Retransmission Timeout,RTO)。如果在定时器到期前,没有收到ACK,那就就会假定,数据包丢失,就要重传。RTO是根据RTT(Round-Trip Time,RTT)计算来的,更进一步,其实是基于SRTT(RTT的加权平均值)和RTTVAR(RTT的偏差)计算得到的。RTO是动态变化的,每收到一个ACK或者重传开始后,收到一个ACK或者定期,三种方式来触发更新。其中,为了避免重传时,网络还是有较大的不确定性,一些实现上,也会在重传时,延迟进行RTO的更新。

快速重传

原理

当发送方连续收到3个重复的ACK时,就会立刻重传丢失的那个数据包,不等待超时。之所以一定要收到3个再重传,而不是1个或者2个,这是因为,如果只是偶尔的网络抖动或数据包重排序等暂时性现象,导致接收方没收到包,发送方其实没必要立刻重传。这种机制通过增加重传的触发门槛,提高了对丢包检测的准确性,从而优化了网络资源的利用和数据传输的效率。以下,是它的工作流程示例:

  1. 发送数据包

    • 发送方发送一系列数据包,如包1, 2, 3, 4。
  2. 接收方检测丢失

    • 接收方如果只收到数据包1和3,发现数据包2丢失,会发送ACK(1),表示期望收到序列号为2的数据包。
    • 此时,ACK(1)是第一个重复的ACK。
  3. 重复ACK计数

    • 发送方收到第一个重复的ACK(1)时,不立即重传数据包2,而是等待更多的ACK来确认丢失情况。
    • 当接收方再次收到数据包3或其他后续数据包时,会继续发送ACK(1),累计到三个重复的ACK(1)。
  4. 触发快速重传

    • 发送方收到第三个重复的ACK(1)后,确认数据包2确实丢失,立即重传数据包2。
    • 发送方继续发送后续数据包,恢复正常传输。

选择性确认(SACK)

原理

升级版的确认机制。接收方回复某个ACK确认包的时候,同时这个数据的TCP可选字段中,还有一个SACK选项,它会分成一个或者多个SACK块,每个块代表我已经收到了什么数据包(通过起始、结束序列号来表示出具体的数据部分)。这样发送方就能明白,原来漏掉了是xx号,接收方已经收到了其他的,那我只要重传xx号的数据包即可。而普通的ACK确认机制,发送方收到要重传某个数据包后,他不知道接收方在此数据包之后的数据包有没有收到,于是干脆把后面的数据包也全部都重传了,这样效率肯定会比SACK低一些。SACK并不是默认开启的,因为它要求客户端、服务器都支持SACK。当前,大多数操作系统,默认都是开启的。是否开启SACK,这会在三次握手的过程中进行确认:

  • 如果双方都在SYN包中包含SACK-Permitted选项,则SACK在该连接中被启用;
  • 如果任一方不支持或未包含SACK-Permitted选项,则该连接中不会使用SACK。

以下,是它的工作流程示例:

    • 发送方发送数据包1、2、3、4、5、6,其中2丢失了;
    • 接收方收到数据包后,发送ACK(1)(表示期望收到的数据段序列号是2)和
SACK选项
    • SACK块1:起始序列号3,结束序列号4
    • SACK块2:起始序列号5,结束序列号6
  • 发送方根据SACK信息,重传数据包2,而不重传3、4、5、6。
posted @   1234roro  阅读(56)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示