浅谈TCP/IP四种计时器、慢启动、拥塞避免、快速重传、快速恢复

持续计时器

解决的问题:A给B发送数据,如果B告诉A自己的缓冲区已满,于是A停止发送数据,等待一段时间后,B的缓冲区出现了富余,于是给A发送报文告诉rwnd大小为400,但是这个报文不幸丢失了,于是就出现A等待B的通知,B等待A发送数据的死锁状态,为了处理这种问题,TCP引入了持续计时器。

持续计时器:当A收到B的零窗口通知时,就启用该计时器,时间到则发送一个字节的探测报文,对方会在此时回应自身的接收窗口大小,如果仍然为0,则重置持续计时器,继续等待.

重传计时器(RTO)

当TCP发送报文段时,就创建该特定报文段的重传计时器,可能发-生两种情况:

若在计时器截止时间到之前收到了对此特定报文段的确认,则撤销此计时器.
若在计时器截止时间到之前没有收到对此特定报文段的确认,则重传此报文段,并将计时器复位.

保活计时器

问题:假定客户端打开了服务器的连接,传送了一些数据,然后就保持静默,也许这个客户端出故障了,在这种情况下,这个连接将永远保持打开状态,浪费资源。

服务器设置保活计时器解决上面的问题,每当服务器收到客户端的信息,就将计时器复位,超时通常设置为2小时,若服务器过了2小时还没有收到客户端的信息,就发送探测报文段,若发送10个探测报文段(每一个相隔75秒)还没有响应,就假定客户端除了故障,因而就终止该连接.

时间等待计时器

 和TCP三次同步握手不一样的是,TCP关闭连接用四次挥手来实现,即A—–>B Fin,B—->A ACK, B—–>A Fin,A—-B ACK 
A属于主动关闭方,收到B的ACK之后,A到B的方向连接关闭,即half shutdown,这时不能再发送数据了. 
这种状态下B还是可以单向发送数据的,B的数据发送完毕,也可以做关闭动作了, 
B——>A Fin,A——> B ACK 
B收到ACK,关闭连接,但是A无法知道ACK是否已经到达B,于是开始等待?等待什么呢,假如ACK没有到达B,B会为FIN这个消息超时重传,那如果A等待时间足够,又收到FIN消息,说明ACK没有到达B,于是再发送ACK,直到在足够的时间内没有收到FIN,说明ACK成功到达,这个等待时间至少是:B的timeout+FIN的传输时间,为了保证可靠,采用更加保守的等待时间2MSL. 
MSL:报文段最大生存时间MSL.它是任何报文段被丢弃前网络内的最长时间。 
TTL:IP对IP 数据报生存时间限制,255秒,所以MSL一般=TTL = 255 秒 
A发出ACK,等待ACK到达对方的超时时间MSL,等待FIN的超时重传,也是MSL,所以如果2MSL时间内没有收到FIN,说明对方安全收到FIN。

慢启动

最初的TCP在连接建立成功后会向网络中发送大量的数据包,这样很容易导致网络中路由器缓存空间耗尽,从而发生拥塞。因此新建立的连接不能够一开始就大量发送数据包,而只能根据网络情况逐步增加每次发送的数据量,以避免上述现象的发生。具体来说,当新建连接时,cwnd(拥塞窗口)初始化为1个最大报文段(MSS)大小,发送端开始按照拥塞窗口大小发送数据,每当有一个报文段被确认,cwnd就增加当前cwnd个MSS大小。这样cwnd的值就随着网络往返时间(Round Trip Time,RTT)呈指数级增长,事实上,慢启动的速度一点也不慢,只是它的起点比较低一点而已。我们可以简单计算下:

开始 ——> cwnd = 1 
经过一个RTT 后(即收到一个ACK后)  cwnd = 2*1 = 2 
经过两个RTT后(即收到两个ACK后)  cwnd = 2*2 =4 
经过三个RTT后(即收到两个ACK后)  cwnd =2*2*2 = 8

拥塞避免

从慢启动可以看到,cwnd可以很快的增长上来,从而最大程度的利用网络带宽资源,但是cwnd不能一直这样无限增长下去,一定需要某个限制。TCP使用了一个叫慢启动门限(ssthresh)的变量,当cwnd超过该值后,慢启动过程结束,进入拥塞避免阶段。对于大多数TCP实现来说,ssthresh的值是65536(同样以字节计算)。拥塞避免的主要思想是加法增大,也就是cwnd的值不再指数级往上升,开始加法增加。此时当窗口中所有的报文段都被确认时,cwnd的大小加1,cwnd的值就随着RTT开始线性增加,这样就可以避免增长过快导致网络拥塞,慢慢的增加调整到网络的最佳值。

上面讨论的两个机制都是没有检测到拥塞的情况下的行为,那么当发现拥塞了cwnd又该怎样去调整呢?

首先来看TCP是如何确定网络进入了拥塞状态的,TCP认为网络拥塞的主要依据是它重传了一个报文段。上面提到过,TCP对每一个报文段都有一个定时器,称为重传定时器(RTO),当RTO超时且还没有得到数据确认,那么TCP就会对该报文段进行重传,当发生超时时,那么出现拥塞的可能性就很大,某个报文段可能在网络中某处丢失,并且后续的报文段也没有了消息,在这种情况下,TCP反应比较“强烈”: 
1.把ssthresh 降为cwnd值的一半. 
2.把cwnd重新置为1 
3.重新进入慢启动过程。 
从整体上来讲,TCP拥塞控制窗口变化的原则是AIMD原则,即加法增大、乘法减小。可以看出TCP的该原则可以较好地保证流之间的公平性,因为一旦出现丢包,那么立即减半退避,可以给其他新建的流留有足够的空间,从而保证整个的公平性。

快速重传

TCP需要立刻产生一个ACK,这个ACK不应该被延时,目的在于让对方知道收到一个失序的报文,并告诉对方自己希望收到的报文seq,我们不知道这个重复的ACK的原因,因为还是会等待少量的重复ACK到来,如果连续收到3个或者3个以上的dup ACK,就被判断这个报文被丢失了。快速重传:于是就需要立即重传丢失的数据段,这个地方不用等待重传定时器溢出。

快速恢复

后来的“快速恢复”算法是在上述的“快速重传”算法后添加的,当收到3个重复ACK时,TCP最后进入的不是拥塞避免阶段,而是快速恢复阶段。快速重传和快速恢复算法一般同时使用。快速恢复的思想是“数据包守恒”原则,即同一个时刻在网络中的数据包数量是恒定的,只有当“老”数据包离开了网络后,才能向网络中发送一个“新”的数据包,如果发送方收到一个重复的ACK,那么根据TCP的ACK机制就表明有一个数据包离开了网络,于是cwnd加1。如果能够严格按照该原则那么网络中很少会发生拥塞,事实上拥塞控制的目的也就在修正违反该原则的地方。 
1.当收到3个重复ACK时,把ssthresh设置为cwnd的一半。 
2.在收到重复的ACK时,拥塞窗口增加1。

3 把cwnd设置为ssthresh的值加3,然后利用快速重传机制重传丢失的报文段,加3的原因是因为会收到3个重复的ACK,表明有3个“老”的数据包离开了网络
4.当收到新的数据包的ACK时,把cwnd设置为第一步中的ssthresh(即原本cwnd的一半)的值。原因是因为该ACK确认了新的数据,说明从重复ACK时的数据都已收到,该恢复过程已经结束,可以回到拥塞避免状态了。

快速恢复和拥塞避免的主要区别是在遇到报文丢失的场景时,拥塞避免会直接将cwnd置为1,而快速恢复则是先执行快速重传,然后将cwnd减半。


借鉴:https://blog.csdn.net/whoamiyang/article/details/54943687 --对快速重传理解不太对

https://blog.csdn.net/jtracydy/article/details/52366461--借鉴快重传的理解

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值