名詞解釋:
cwnd -- 擁塞窗口
ssthresh(slow start threshold)-- 慢啓動到擁塞避免到閾值
RTT——Round Trip Time,也就是一個數據包從發出去到回來的時間
RTO(Retransmission TimeOut)重發超時時間
爲何有了滑動窗口還須要有擁塞窗口?
滑動窗口是對發送接收雙方的流量控制,若是中間的網絡設備的轉發性能達到極限是沒法感知到的,而tcp除了針對自身的收發能力作調整,還根據總體的網絡狀況作調整,因此有了擁塞窗口。
擁塞控制分爲四個階段,每一個階段的處理策略都不一樣,大概就是先猛增,而後當心增加預防擁塞,還有就是已經發生擁塞了的措施和快速恢復。
慢啓動
此階段的操做:
cwnd設置爲一個很小的初始值,這個初始值在不一樣版本里面是不同的,有一、三、10等。
每收到一個ack,cwnd = cwnd+1
cwnd*2
cwnd成指數級別遞增。
跳出該階段的標誌:cwnd等於ssthresh時,進入擁塞避免階段,那麼ssthresh的值該設置成多少?將在後面介紹。
擁塞避免
此階段的操做:
收到一個ACK時,cwnd = cwnd + 1/cwnd
當每過一個RTT時,cwnd = cwnd + 1
此階段cwnd成線性增加。
跳出該階段的標誌:發生擁塞,此時進入發生擁塞階段
發生擁塞
分爲兩種狀況:
1)RTO超時,重傳數據包。TCP認爲這種狀況網絡上很糟糕了,反應也很強烈。算法
sshthresh = cwnd /2網絡
cwnd 重置爲初始值ssh
進入慢啓動過程tcp
2)收到3個duplicate ACK,這種狀況認爲網絡狀況還能夠,反應不是很強烈。性能
cwnd = cwnd /2spa
sshthresh = cwndip
進入快速恢復階段it
跳出該階段的標誌:出現一下,處理以後必然跳出到其餘狀態。io
爲何快速恢復中會收到多個相同的ack,以及爲何認爲收到多個相同ack要比RTO的網絡狀況好? 將在後面介紹。ast
快速恢復
cwnd = sshthresh + 3 * MSS (3的意思是確認有3個數據包被收到了)
重傳Duplicated ACKs指定的數據包
若是再收到 duplicated Acks,那麼cwnd = cwnd +1
若是收到了新的Ack,那麼,cwnd = sshthresh ,而後就進入了擁塞避免的算法了
跳出該階段的標誌:出現一下,處理以後必然跳出到其餘狀態。
ssthresh的值該設置成多少?
動態的,由於不一樣設備,不一樣網絡環境中網絡等承載能力是不一樣的,初始值會設置很大,
#define TCP_INFINITE_SSTHRESH 0x7fffffff,而後按照上面介紹的到了擁塞發生階段,sshthresh會被設置成擁塞發生時候,擁塞窗口的一半。
爲何快速恢復中會收到多個相同的ack,以及爲何認爲收到多個相同ack要比RTO的網絡狀況好?
這個是tcp的快速重傳機制,接收方若是收到的包不連續,從斷點開始,每次收到新包,都ack丟失點的序號,若是發送方連續收到3次相同的ack,就重傳。Fast Retransmit的好處是不用等timeout了再重傳。舉例:若是發送方發出了1,2,3,4,5份數據,第一份先到送了,因而就ack回2,結果2由於某些緣由沒收到,3到達了,因而仍是ack回2,後面的4和5都到了,可是仍是ack回2,由於2仍是沒有收到,因而發送端收到了三個ack=2的確認,知道了2尚未到,因而就立刻重轉2。而後,接收端收到了2,此時由於3,4,5都收到了,因而ack回6。從上面也能看出收到三個相同的2的ack,起碼說明網絡中還能正常來回傳輸3,4,5等,說明網絡還有的救,因此反應沒那麼激烈,而RTO說明這段時間不單單是2丟了,並且2丟了這段時間尚未收到後面的3個包,因此tcp就認爲網絡比較糟糕了,反應也比較激烈。