快速重传
在超时重传中,重点是定时器溢出超时了才认为发送的数据包丢失,快速重传机制,实现了另外的一种丢包评定标准,即如果我连续收到3次dup ACK,发送方就认为这个seq的包丢失了,立刻进行重传,这样如果接收端回复及时的话,基本就是在重传定时器到期之前,提高了重传的效率。
如果只出现两次dup ACK 我们可能会认为只是失序如果收到一个out-of-order的报文段时, TCP需要立刻产生一个ACK。所以收到3个dup ACK 或者以上我们就会认为是丢失了。
在传输过程中会出现out-of-order的现象,但是在滑动窗口中会有严格的顺序控制,假设有4,5,6三个待接收的数据包,先收到了5,6,协议栈是不会回复对5,6包的确认,而是根据TCP协议的规定,当接收方收到乱序片段时,需要重复发送ACK, 在这个地方会发送报文4 seq的ACK,表明需要报文4没有被接收到,如果此后收到的是报文7,那么仍然要回报文4 seq的ACK,如果连续发送3个 dup ACK,接收端(这里的接收端其实就是发送数据端)认为这个片段已经丢失,进行快速重传。
快速恢复算法
快速重传和快速恢复算法一般同时使用。快速恢复算法是认为,你还有3个Duplicated Acks说明网络也不那么糟糕,所以没有必要像RTO超时那么强烈,并不需要重新回到慢启动进行,这样可能降低效率。所以协议栈会做如下工作
-
cwnd = cwnd/2
-
sshthresh = cwnd
然后启动快速恢复算法:
-
设置cwnd = ssthresh+ACK个数*MSS(一般情况下会是3个dup ACK)
-
重传丢失的数据包(对于重传丢失的那个数据包,可以参考TCP-IP详解:SACK选项)
-
如果只收到Dup ACK,那么cwnd = cwnd + 1, 并且在允许的条件下发送一个报文段
-
如果收到新的ACK, 设置cwnd = ssthresh, 进入拥塞避免阶段