快速重傳演算法在之前的文章中有介紹,如果收到乙個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的傳輸效率,這個演算法的示意圖如下,可以看到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又要減半進入快速恢復階段....
這個演算法是reno演算法的改進,沒有使用sack機制
快速恢復與快速重傳演算法
擁塞避免演算法的修改建議1 9 9 0年提出 jacobson 1990b 在介紹修改之前,我們認識到在收到乙個失序的報文段時,tcp立即需要產生乙個ack 乙個重複的ack 這個重複的ack不應該被遲延。該重複的ack的目的在於讓對方知道收到乙個失序的報文段,並告訴對方自己希望收到的序號。由於我們...
快速重傳與快速恢復演算法
擁塞避免演算法的修改建議1 9 9 0年提出 jacobson 1990b 在介紹修改之前,我們認識到在收到乙個失序的報文段時,tcp立即需要產生乙個ack 乙個重複的ack 這個重複的ack不應該被遲延。該重複的ack的目的在於讓對方知道收到乙個失序的報文段,並告訴對方自己希望收到的序號。由於我們...
TCP快速重傳和快速恢復
當tcp傳送乙個分組時會設定乙個定時器,如果在規定的實際間隔內沒有收到ack分組,那麼則重新傳輸該分組,但是 如果tcp收到三個連續的ack分組,此時不管是否過超時間隔則重傳該分組,具體步驟如下 1.將慢啟動閾值ssthresh設為擁塞視窗 cwnd 可理解為傳送資料報大小 的一半 2.對於連續三個...