快速恢复算法是相对于快速重传来说的。所以先认识一下快速重传:
当TCP接收端收到一个失序的报文时,会立即产生一个ACK(一个重复的ack,即并不是对这个失序报文的确认,而是上一个已确认的报文的ACK),这个ack不应该被延迟。这个ack的目的是让发送方知道接收方真正希望接收的报文。
也正是因为上述的这种ack,从而我们不能确认一个重复的ack是因为什么原因发送的,是一个报文丢失了,还是一个对方收到了一个失序的报文产生的。因此在TCP发送端的处理是会等待少量的ack到来,通常认为失序产生的ack一般不会超过两个(这里失序的情况有可能是同一个失序报文在网络中存在多个拷贝,如果是这种理解的话应该是不大可能超过2个,因为多个相同的拷贝到达同一个目的网络,这说明网络拓扑可能本身存在了问题,存在多条不同的代价的路径而不是只优选最优路径。当然这里也可能是多个不同的失序报文,这样的话就完全有可能超过2个,但是这种大部分的可能就是有某个报文被丢失了,这里就需要重传)。如果在一个RTT时间段中接收到了3个或者3个以上的ack,那么这就刚括号中分析的那样,很可能就是某个报文丢失了。
对于这种报文丢失的情况可以有两种方案进行选择:
1.在RTT时间到期时进行慢启动,遵循拥塞避免算法中的慢启动情形。
2.不等待RTT时间到期,直接重传丢失的数据。这就是快速重传的机制。
这里TCP为什么选择快速重传:
主要是因为发送方一直都有收到对端的ack,这个说明网络质量是好的,至少并没有明显的拥塞发生,因为对端能够发送ack是因为收到了一个报文,即说明网络是相对畅通的,它能够一个一个的收到报文发送出ack。所以并不需要采用慢启动来降低网络利用率。
那么问题来了,既然不用慢启动,那么当直接重传丢失的报文,下一步TCP会怎么做?
快速恢复算法来解决:
1.当收到第三个ack时,将ssthresh设置成当前cwnd的一半,设置cwnd为ssthresh+接受的ack个数*MSS,发送重传的数据报。
2.在没有收到新数据的ack之前,每收到一个重复的ack,cwnd就增加1个报文段。并在允许的情况下发送一个报文段(这里的允许条件是cwnd的大小要大于未被确认的报文大小)。
3.当收到了新数据的ack时,设置cwnd为ssthresh的值(为发生重传时窗口的一半)。这个时候后续就开始了拥塞避免算法,因为cwnd >= ssthresh,所以并不是拥塞中的慢启动。
阅读(11961) | 评论(0) | 转发(0) |