基本概念
在講擁塞控制之前,先眼熟幾個概念rwnd(接收窗口)、cwnd(擁塞窗口)、ssthresh(慢啟動門限)
我們都知道,TCP是通過每次在首部設置接收窗口的大小來控制流量傳輸而不導致接收緩存溢出的。
而擁塞控制則是加了個擁塞窗口來維護,擁塞窗口只是個狀態量,並沒有在TCP首部。而TCP的發送窗口
取決與擁塞窗口和接收窗口的。發送窗口就是擁塞窗口和接收窗口的最小值。即min(rwnd,cwnd)。了解了
這么些概念后我們接着往下看。
網絡擁塞的定義
當發生了超時重傳或者冗余ACK的時候我們就可以認定發生了網絡擁塞,這時候就需要進行擁塞控制。而正常
的收發報文段即發送端發送分組,接收方發送確定ACK分組則認為網絡流程。不需要擁塞控制。
擁塞控制算法
當連接建立的時候cwnd默認值為一個報文段,ssthresh默認為65535個字節。
慢啟動算法
慢啟動算法的執行條件是cwnd<=ssthresh。連接剛建立cwnd = 1,進入慢啟動算法。慢啟動算法是當網絡流通時,
即沒有發生超時重傳和冗余ACK重傳客戶端TCP每接收到一個接收段的ACK就將 cwnd x 2,就是將擁塞窗口翻倍。
當發生超時重傳后將ssthresh設置為當前窗口大小的一般,即 min(cwnd,rwnd)/ 2,然后將cwnd設置為1,重新
進入慢啟動。當發生冗余ACK重傳報文段的時候則進入快重傳快恢復階段,快重傳快恢復下面會將。還有一種情況
就是當cwnd > ssthresh的時候就認為當前網絡很有可能發生擁塞,不能在那么快的提高擁塞窗口的大小了,這時候
就進入擁塞避免階段,擁塞避免階段也會將。
因此我們可以總結出進入慢啟動算法的條件是擁塞窗口小於等於慢啟動門限。而退出慢啟動算法進入其他算法則是有
三種情況:1、出現了超時重傳;2、出現了冗余ack;3、擁塞窗口大於慢啟動門限。
擁塞控制算法
當擁塞窗口大於慢啟動門限的時候就會進入擁塞控制,這時候擁塞窗口就不再采用指數增長而是進行線性增長,即每次
cwnd + 1。當出現超時重傳的處理方法和慢啟動出現超時重傳的處理方法相同,即ssthresh = min(cwnd,rwnd) / 2
cwnd = 1。然后進入慢啟動算法。當出現冗余ack的時候則進入快重傳,快恢復算法。
因此進入擁塞控制的前提是:擁塞窗口大於慢啟動門限。而退出擁塞控制的條件是擁塞窗口小於慢啟動門限。
快重傳、快恢復算法
當出現冗余ack的時候我們就可以認為ack確認的報文段的下一個報文段丟失了,我們這時候需要快速將該報文段發送給接收方,
然后將慢啟動門限設置為當前窗口的一半,即ssthresh = min(cwnd,rwnd)/2,並且cwnd = ssthresh。直接進入擁塞避免。
為什么后面不將cwnd設為1進入慢啟動呢,我們認為當出現冗余ack而重傳下一個報文段的時候嚴格上不算是擁塞導致的。所以
直接進入擁塞避免。
總結
經過上述的描述我們可以對整個擁塞避免流程做個小總結
當出現超時重傳和冗余ack的時候慢啟動門限都要設置為當前發送窗口的一半,不同的就是超時重傳還得將擁塞窗口大小設為1,重新
進入慢啟動,而冗余ack則是將擁塞窗口設為慢啟動門限大小並且進入擁塞避免。