TCP-IP详解:快速重传与快速恢复
快速重傳算法
快速重傳算法在之前的文章中有介紹,如果收到一個out-of-order的報文段時, TCP需要立刻產生一個ACK,這個ACK不應該被延時,目的在于讓對方知道收到一個失序的報文,并告訴對方自己希望收到的報文seq,我們不知道這個重復的ACK的原因,因為還是會等待少量的重復ACK到來,如果連續收到3個或者3個以上的dup ACK,就被判斷這個報文被丟失了,于是就需要立即重傳丟失的數據段,這個地方不用等待定時器溢出。更詳細的介紹可以參考:TCP-IP詳解:超時重傳機制
?
快速恢復算法
TCP Reno這個算法定義在RFC5681。快速重傳和快速恢復算法一般同時使用。快速恢復算法是認為,你還有3個Duplicated Acks說明網絡也不那么糟糕,所以沒有必要像RTO超時那么強烈,并不需要重新回到慢啟動進行,這樣可能降低效率。所以協議棧會做如下工作
1. ?cwnd = cwnd/2?
2. sshthresh = cwnd?
然后啟動快速恢復算法:
1.?設置cwnd = ssthresh+ACK個數*MSS(一般情況下會是3個dup ACK)
2. 重傳丟失的數據包(對于重傳丟失的那個數據包,可以參考TCP-IP詳解:SACK選項)
3. 如果只收到Dup ACK,那么cwnd = cwnd + 1, 并且在允許的條件下發送一個報文段
4. 如果收到新的ACK, 設置cwnd = ssthresh, 進入擁塞避免階段
?
TCP Reno算法
其實TCP Reno算法就是在慢啟動和擁塞避免的基礎上增加了快速重傳和快速恢復算法,避免了在擁塞不嚴重的狀況下,過大的減小擁塞窗口,降低TCP的傳輸效率,這個算法的示意圖如下,可以看到cwnd在遇到3個dup ACK的時候 cwnd減半,進入快速恢復模式.
這個算法存在的一個問題是,多個報文同時丟失的情況下會出現性能問題,系統會多次執行快速重傳和快速恢復算法,多次降低cwnd的值,降低了傳輸的效率。
可以看下Reno丟失2個包的狀況了
1. cwnd = 10?
2. 發送數據包,但是3包和6包丟失
3. 收到數據包1的ACK, cwnd = 11
4. 收到數據包2的ACK, ?cwnd = 11
5. 收到數據包2的Dup ACK,cwnd = 11
6. 收到數據包2的Dup ACK, cwnd = 11
7. 收到數據包2的dup ACK, cwnd = 11 , 3個dup ACK,啟動快速重傳算法,立即發送數據包3,然后進入快速恢復階段
8. ssh = 11/2 = 5 ?cwnd = 5+3 = 8
9. 收到一個dup ACK cwnd + 1 ?直到收到一個新的ACK,cwnd = ssh = 5 ?進入擁塞避免階段
10. 可是又連續收到dup ACK,進行快速重傳,cwnd又要減半進入快速恢復階段....?
?
?
TCP New Reno
這個算法是Reno算法的改進,沒有使用SACK機制
- 當sender這邊收到了3個Duplicated Acks,進入Fast Retransimit模式,開始重傳重復Acks指示的那個包。如果只有這一個包丟了,那么,重傳這個包后回來的Ack會把整個已經被sender傳輸出去的數據ack回來。如果沒有的話,說明有多個包丟了。我們叫這個ACK為Partial ACK。
- 一旦Sender這邊發現了Partial ACK出現,那么sender就可以推理出來有多個包被丟了,于是乎繼續重傳sliding window里未被ack的第一個包。直到再也收不到了Partial Ack,才真正結束Fast Recovery這個過程
總結
以上是生活随笔為你收集整理的TCP-IP详解:快速重传与快速恢复的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 浅析TCP之SACK(选择性确认)
- 下一篇: libcurl 域名解析分析