擁塞避免算法的修改建議1 9 9 0年提出 [Jacobson 1990b]。
在介紹修改之前,我們認識到在收到一個失序的報文段時, TCP立即需要產生一個ACK(一個重復的ACK)。這個重復的ACK不應該被遲延。該重復的ACK的目的在於讓對方知道收到一個失序的報文段,並告訴對方自己希望收到的序號。
由於我們不知道一個重復的ACK是由一個丟失的報文段引起的,還是由於僅僅出現了幾個報文段的重新排序,因此我們等待少量重復的ACK到來。假如這只是一些報文段的重新排序,則在重新排序的報文段被處理並產生一個新的ACK之前,只可能產生1 ~ 2個重復的ACK。
如果一連串收到3個或3個以上的重復ACK,就非常可能是一個報文段丟失了。於是我們就重傳丟失的數據報文段,而無需等待超時定時器溢出。這就是快速重傳算法。接下來執行的不是慢啟動算法而是擁塞避免算法。這就是快速恢復算法。
在下圖中可以看到在收到3個重復的ACK之后沒有執行慢啟動。相反,發送方進行重傳,接着在收到重傳的ACK以前,發送了3個新的數據的報文段(報文段67, 69和7 1)。
在這種情況下沒有執行慢啟動的原因是由於收到重復的ACK不僅僅告訴我們一個分組丟失了。
由於接收方只有在收到另一個報文段時才會產生重復的ACK,而該報文段已經離開了網絡並進入了接收方的緩存。也就是說,在收發兩端之間仍然有流動的數據,而我們不想執行慢啟動來突然減少數據流。
這個算法通常按如下過程進行實現:
1) 當收到第3個重復的ACK時,將ssthresh設置為當前擁塞窗口cwnd的一半。重傳丟失的報文段。設置cwnd為ssthresh加上3倍的報文段大小。
2) 每次收到另一個重復的ACK時,cwnd增加1個報文段大小並發送 1個分組(如果新的cwnd允許發送)。
3) 當下一個確認新數據的ACK到達時,設置cwnd為ssthresh(在第1步中設置的值)。這個
ACK應該是在進行重傳后的一個往返時間內對步驟 1中重傳的確認。另外,這個ACK也應該是對丟失的分組和收到的第1個重復的ACK之間的所有中間報文段的確認。這一步采用的是擁塞避免,因為當分組丟失時我們將當前的速率減半。
快速重傳算法最早出現在 4.3BSD Ta h o e版本中,但它隨后錯誤地使用了慢啟動。
快速恢復算法出現在4.3BSD Reno版本中。