14.1 引言
TCP提供可靠的数据传输服务,为了保证数据传出的正确性,TCP重传其认为已丢失的数据包(或是SACK确认的丢失数据包),TCP根据接收端返回值发送端的一些列ACK来确认是否出现丢包。
当出现丢包,再适合的时候,TCP启动重传,重传肠胃确认的数据。
TCP有两套独立的机制来完成重传:基于时间,基于信息构成,第二种更加高效。
TCP发送数据是,会设置一个计时器,若计时器超时未收到数据包的ACK,则会引发相应的超时或基于计时器的重传操作,计时器超时称为重传超时RTO
另一中重传方式称为快速重传,通常发生在没有延时的视情况,若ACK累计无法确认返回新的ACK(返回的可能是重复ACK),或是包含选择确认信息SACK,快速重传会推断出现丢包。
14.2 简单的超时与重传
每次重传间隔时间加倍称为二进制指数退避
TCP拥有两个阈值来决定如何重传一个报文段,R1表示TCP在想IP层传递消极建议前(例如重新评估当前IP路径),愿意重传的次数(或等待的时间)。R2(大于R1)指示TCP应放弃当前连接的时机。
R1通常为3次,R2冲肠胃3分钟。
14.3 设置重传超时
TCP超时和重传的基础是怎么根据连接的RTT里设置RTO。
TCP在收到ACK时,根据数据报中携带的数据来测量该确认信息所需的时间。每个这样的测量结果称为RTT样本。
14.3.1 经典方法
指数加权移动平均:
SRTT=a(SRTT) + (1-a)RTT
也就是,每次的SRTT根据得到的RTT更新,a是一个平滑因子,一般为0.8~0.9.
经典方法:
RTO=min(max_value,max(min_value,(SRTT)*b))
其中max_value和min_value是超时等待的上限和下限。b是一个时延离散因子去1.2~1.3
缺点:无法适应大规模的变动,因为新旧RTT的比重不同,因此变化会有延迟。
14.3.2 标准方法
在测量的时候同时测量均值和方差,
再看
14.3.2.1 时钟粒度与RTO
14.3.3 Linux采用的方法
14.4 基于计时器的重传
14.5 快速重传
基于ACK
ACK分组的ACK值,永远是已收到连续数据的最后一个字节的偏移量+1。也就是出现第一个空洞的位置。
当失序数据到达时,ACK立即返回,不能延时发送。因此发送端会连续收到ACK值相同的ACk分组。当发送端收到相同ACK分组的次数达到重传的重复ACK阈值(dupthresh),就会重传对应的分组。
快速重传算法概括为:TCP发送端在观测到至少dupthresh个重复ACK后,即重传可能丢失的数据分组,而不必等待计时器超时。当然也同时发送新的数据。不采用SACK时,在接收到有效ACK(ACK值不在是重复的)之前只能重传一个报文段。
NewReno算法
统计|流图小竖杠是发送端发送的数据报的Seq值。下面的连续梯形是发送端接收到的数据报的ACK值。
如果连续观测到超过dupthresh个重复ACK,开吃重传,当前已发送数据报的Seq最大值成为恢复点。发送丢失数据,同时还继续发送新的数据。以后,当收到新的ACK,如果ACK值小于恢复点,那么立即重传新的丢失的数据,直到ACK超过恢复点,重传结束。
14.6 带选择确认的重传
TCP选择确认选项
TCP接收端提供SACK功能,通过头部累计ACK号字段来描述收到的数据。
ACK号与接收端缓存中其他数据之间的间隔成为空缺。Seq高于空缺数据成为失序数据。
每个SACK信息包括4字节开始位置,4字节结束为止(表示收到数据的起始值最后一个序列号+1),2字节填充。因此一个SACK为10个字节。SACK还会与TSOPT一起使用,又用掉10字节。
所以每个ACK中只能包含3个SACK块。(选项一共40字节)。
第一个SACK块为最新收到的数据,也就是最后的那段,其余两端为从头开始收到的两端连续数据。因此这就有两个空洞了。
发送端在收到SACK以后,不能因为SACK块标记的已接收到数据而清空字节的重传缓存中的数据,必须等待ACK才清除。
这是因为接收端变更:食言。不过很少发生。
14.7 伪超时与重传
14.8 包失序与包重复
每个包可以选择各自的传送路径。某些高级路由器的采用多个并行数据链路,不同的处理演示也会导致包的离开顺序和到达顺序不匹配
包的失序会造成重传,很近单嘛,前面一个小号的Seq没到达,后面的先到达,那么ACK就会 重复
14.9 目的度量
14.10 重新组包
当TCP超时重发是,循序执行重新租宝,发送送一个更大的报文段提高性能,不超过MSS和MTU。
出现在每次传送的包较小,又丢包的情况
网友评论