TCP流量控制

作者:proing

原文地址:http://blog.csdn.net/proing/article/details/2149145

 

1. 前言
 
TCP是具備流控可靠連接能力的協議,爲防止TCP發生擁塞或爲提高傳輸效率,在網
絡發展早期就提出了一些相關的TCP流控和優化算法,而且也被RFC2581規定是每個
TCP實現時要實現的。
 
本文中,爲求方便把將“TCP分組段(segment)”都直接稱爲“包”。
 
2. 慢啓動(slow start)和擁塞避免(Congestion Avoidance)
 
慢啓動和擁塞避免是屬於TCP發送方必須(MUST)要實現的,防止TCP發送方向網絡傳入大量的突發數據造成網絡阻塞。

先介紹幾個相關參數,是在通信雙方中需要考慮但不在TCP包中體現的一些參數:

擁塞窗口(congestion window,cwnd),是指發送方在接收到對方的ACK確認前向允許網絡發送的數據量,數據發送後,擁塞窗口縮小;接收到對方的ACK後,擁塞窗口相應增加,擁塞窗口越大,可發送的數據量越大。擁塞窗口初始值的RFC2581中被規定爲不超過發送方MSS的兩倍,而且不能超過兩個TCP包,在RFC3390中更新了初始窗口大小的設置方法。

通告窗口(advertised window,rwnd),是指接收方所能接收的沒來得及發ACK確認的數據量,接收方數據接收後,通告窗口縮小;發送ACK後,通告窗口相應擴大。

慢啓動閾值(slow start threshold, ssthresh),用來判斷是否要使用慢啓動或擁塞避免算法來控制流量的一個參數,也是隨通信過程不斷變化的。

當cwnd < ssthresh時,擁塞窗口值已經比較小了,表示未經確認的數據量增大,需要啓動慢啓動算法;當cwnd > ssthresh時,可發送數據量大,需要啓動擁塞避免算法。

擁塞窗口cwnd是根據發送的數據量自動減小的,但擴大就需要根據對方的接收情況進行擴大,慢啓動和擁塞避免算法都是描述如何擴大該值的。

在啓動慢啓動算法時,TCP發送方接收到對方的ACK後擁塞窗口最多每次增加一個發送方MSS字節的數值,當擁塞窗口超過sshresh後或觀察到擁塞才停止算法。

啓動擁塞避免算法時,擁塞窗口在一個連接往返時間RTT內增加一個最大TCP包長度的量,一般實現時用以下公式計算:
      cwnd += max(SMSS*SMSS/cwnd, 1)            (2.1)
SMSS爲發送方MSS。

TCP發送方檢測到數據包丟失時,需要調整ssthresh,一般按下面公式計算:
      ssthresh = max (FlightSize / 2, 2*SMSS)    (2.2)
其中FlightSize表示已經發送但還沒有被確認的數據量。
 
3. 快速重傳(fast retransmit)和快速恢復(fast recovery)

TCP接收方收到錯序的TCP包時要發送複製的ACK包迴應,提示發送方可能出現網絡丟包;發送方
收到連續3個重複的ACK包後啓動快速重傳算法,根據確認號快速重傳那個可能丟失的包而不必等
重傳定時器超時後再重傳,普通的重傳是要等到重傳定時器超時還沒收到ACK才進行的。這個算
法是TCP發送方應該(SHOULD)實現的,不是必須。TCP發送方進行了快速重傳後進入快速恢復階段
,直到沒再接收重複的ACK包。

快速重傳和快速恢復具體過程爲:
1. 當收到第3個重複的ACK包時,ssthreh值按公式2.2重新設置;
2. 重傳丟失的包後,將擁塞窗口cwnd設置爲sshresh+3*SMSS,人工擴大了擁塞窗口;
3. 對於每個接收到的重複的ACK包,cwnd相應增加SMSS,擴大擁塞窗口;
4. 如果新的擁塞窗口cwnd值和接收方的通告窗口值允許的話,可以繼續發新包;
5. 當收到下一個ACK確認了新數據時,將cwnd大小調整爲sshresh,減少窗口;對接收方
   來說,接收到重發的TCP包後就要發此ACK確認當前接收的數據。
 
4. 結論
這些算法重點在於保持網絡的可靠性和可用性,防止網絡阻塞造成的網絡崩潰,是相對
比較保守的。
發佈了6 篇原創文章 · 獲贊 8 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章