Linux网络总结之四-TCP超时重传与拥塞控制

一 超时重传
前面我们探讨了TCP连接超时的问题,这是在TCP连接建立之前的可靠性机制,那么TCP是如何在连接建立之后维护可靠性传输的呢?这里我们就要探讨一下超时重传机制。
超时重传往往发生在网络异常的情况下,TCP协议为TCP报文制定了一个定时器,它用于在给定的时间内接收到对端传回来的确认报文,加入超过给定时间确认报文段还没有传回到发送端,这时发送端就会重新发送上次发送的TCP数据包,并且延迟定时器时间限制。表现形式往往就是微信中的消息未能成功发送。
形如如下的TCP报文传送过程:
 
1. Server 发送80个字节 Part1,seq = 1 
2. Server 发送120个字节Part2,Seq = 81
3. Server发送160个字节Part3,Seq = 201,此包由于其他原因丢失
4. Client收到前2个报文段,并发送ACK = 201
5. Server发送140个字节Part4, Seq = 361
7. Server收到Client对于前两个报文段的ACK,将2个报文从窗口中移除,窗口有200个字节的余量
8. 报文3的重传定时器到期,没有收到ACK,进行重传
9. 这个时候Client已经收到报文4,存放在缓冲区中,也不会发送ACK【累计通知,发送ACK就表示3也收到了】,等待报文3,报文3收到之后,一块对3,4进行确认
10. Server收到确认之后,将报文3,4移除窗口,所有数据发送完成
这种方式会面临一个问题:客户端在等待报文3的时候,服务器如何处理报文4, 客户端这个期间内并没有发送任何报文,服务器并不知道报文3和报文4的状态,报文4可能会丢失,也可能会被客户端接收,那么如果超时了,我到底值该发送报文3 ,还是报文3和报文4 呢?
在超时重传机制中存在一个问题,到底应该重传哪个数据报文段,通常有以下两种可能:
1. 只重传超时的数据包,这种方法是最常想到的,比较实用与后面的数据包都能够正常接收的状况,只重传超时的数据包,但是如果比较坏的情况下,丢失了很多封包呢?  那就需要一个一个的等待超时了,很浪费时间。
2. 重传这个片段以及之后的所有包,这种方法在最坏的状况下,看起来效率还是挺高的,但是如果只有一个包丢失,就去重传后面所有接受到的包,流量浪费也是很严重的。
在TCP协议中又引入了一个新的概念SACK。SACK是一个TCP的选项,来允许TCP单独确认非连续的片段,用于告知真正丢失的包,只重传丢失的片段。要使用SACK,2个设备必须同时支持SACK才可以,建立连接的时候需要使用SACK Permitted的option,将其置为true。
如果接收方选择发送带有SACK的ACK,需要遵循如下规则:
1. 第一个block需要指出是哪一个segment触发SACK option ,我认为就是谁乱序了,才会导致SACK
2. 尽可能多的把所有的block填满
3. SACK 要报告最近接收的不连续的数据块
接收端的行为:
1. 数据没有被确认前,都会保持在滑动窗口内
2. 每一个数据包都有一个SACKed的标志,对于已经标示的segment,重新发送的时候会忽略
3. 如果SACK丢失,超时重传之后,重置所有数据包SACKed 标志。
 


发送端发送seg1和seg2,但是接收端的ACK都被drop掉了,超时重传seg1,然后接收端就发了一个D-SACK,告诉发送端3000~3499重复接收,需要接收4000的。
二  拥塞控制
TCP协议还有一个重要的功能模块,就是拥塞控制。它的主要目的是提高网络利用率,降低丢包率。
拥塞控制主要包括四部分:慢启动,拥塞避免,快速重传,快速恢复。
拥塞控制主要受控于发送端向网络一次写入的数据量,计为发送窗口(SWND)。发送端需要选取合理的SWND大小,若SWND太小则网络延迟,若太大则网络拥塞。基于此,我们引入拥塞窗口的概念CWND,在实际中SWND的取值是CWND与RWND中较小值。MSS一般是是TCP数据包每次能够传输的最大数据分段,出现在请求报文段中。
1慢启动与拥塞避免
TCP连接建立好之后,CWND通常被设置为IW,其大小通常是2~4个SMSS。在新内核中,发送端每收到一个确认报文段,其CWND就按式:
CWND+=min⁡(N,SMSS)
N是此次确认中包含的之前未被确认的字节数。所谓慢启动就是TCP连接刚建立时不知道网络的实际情况,需要一种试探方式来平滑增加CWND的大小。
假如不对CWND控制,则慢启动会导致CWND快速膨胀,所以定义一个慢启动门限,当CWND超过该值时,TCP进入拥塞避免阶段。
在拥塞避免阶段CWND线性增长每个RTT增长一个SMSS大小。
慢启动与拥塞避免示意图如下所示:
 
其中发送端判断拥塞发送有两个依据:1:传输超时,TCP重传定时器溢出,2:接收端重复的确认报文。
2 快速重传与快速恢复
前面我们探究到超时重传是要在超时时间之外才能实现数据报文段重传,而这部分的快速重传是指在超时时间之内重传,通常快速重传发生在网络拥塞的情况下。具体的判断方法就是:发送端连续收到3个相同序列号的ACK之后就认定网络出现拥塞。这时,就可以启动快速重传与快速恢复。
1)收到第3个ACK之后,先计算慢启动门限值ssthresh,然后计算CWND。
ssthresh=max(FlightSize/2,2*SMSS)
其中FlightSize是已经发送但未收到确认的字节数。
计算出新的ssthresh之后,然后重传丢失报文段。重新计算CWND。
CWND= ssthresh+3*SMSS
2)没收到一个确认报文之后就执行CWND+=SMSS。
3)当收到新数据的确认时,设置CWND= ssthresh。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值