TCP的擁塞控制(Congestion Control)是核心機制之一,用于動態調整發送方的數據傳輸速率,避免網絡因過載而出現性能急劇下降(如丟包、延遲激增)。其核心思想是探測網絡可用帶寬,并在擁塞發生時主動降低速率。以下是TCP擁塞控制的詳細解析:
一、擁塞控制的目標
避免擁塞:預防網絡進入過載狀態。
公平性:多個TCP連接共享帶寬時,應公平競爭。
高效性:盡可能利用可用帶寬。
二、核心機制
TCP擁塞控制通過擁塞窗口(Congestion Window, cwnd)實現,它限制了發送方未確認數據的最大量(與接收方的滑動窗口共同決定實際發送窗口)。擁塞控制分為四個階段:
1. 慢啟動(Slow Start)
目的:快速探測網絡可用帶寬。
規則:
初始cwnd = 1 MSS(最大報文段大小,如1460字節)。
每收到一個ACK,cwnd?指數增長(即每RTT翻倍:1 → 2 → 4 → 8...)。
終止條件:
達到慢啟動閾值(ssthresh)時,進入擁塞避免階段。
檢測到擁塞(如丟包)時,重置ssthresh = cwnd/2,cwnd = 1,重新慢啟動。
2. 擁塞避免(Congestion Avoidance)
目的:線性增長避免觸發擁塞。
規則:
每RTT(往返時間)cwnd?增加1 MSS(線性增長,如8 → 9 → 10...)。
終止條件:
發生擁塞(超時或重復ACK)時,調整ssthresh和cwnd。
3. 快速重傳(Fast Retransmit)
觸發條件:收到3個重復ACK(表明報文段丟失,但后續數據仍能到達)。
動作:
立即重傳丟失的報文段(無需等待超時)。
進入快速恢復階段。
4. 快速恢復(Fast Recovery)
目的:在快速重傳后平滑恢復,避免突然降速。
規則:
設置?ssthresh = cwnd/2,cwnd = ssthresh + 3 MSS(補償已確認的3個重復ACK)。
每收到一個重復ACK,cwnd增加1 MSS。
收到新數據的ACK時,退出快速恢復,進入擁塞避免階段。
三、擁塞控制的觸發事件
超時重傳(Timeout):
視為嚴重擁塞,直接重置?cwnd = 1,重新慢啟動。
重復ACK(DupACK):
觸發快速重傳和快速恢復,對擁塞響應更溫和。
四、擁塞控制算法演進
1. Tahoe(早期版本)
發生任何擁塞(超時或重復ACK)均重置cwnd=1,效率較低。
2. Reno(改進版)
引入快速恢復,區分超時和重復ACK,減少激進降速。
3. NewReno(優化版)
改進快速恢復,避免多次丟包時頻繁退出恢復階段。
4. CUBIC(Linux默認)
使用立方函數替代線性增長,更適合高帶寬延遲網絡(BDP)。
五、實例分析
假設初始參數:cwnd=1 MSS,ssthresh=16 MSS,MSS=1460字節。
慢啟動階段:
發送1個報文 → ACK → cwnd=2 → 發送2個報文 → ACKs → cwnd=4 → ...(指數增長)。
擁塞避免階段(cwnd≥16):
每RTT cwnd增加1 MSS(如16 → 17 → 18...)。
快速重傳與恢復:
若收到3個重復ACK,重傳丟失報文,設置cwnd=10(假設原cwnd=20),繼續線性增長。
六、擁塞控制 vs. 流量控制
對比項 | 擁塞控制 | 流量控制 |
---|---|---|
目標 | 避免網絡過載 | 防止接收方緩沖區溢出 |
控制對象 | 網絡鏈路 | 接收方窗口(rwnd) |
實現機制 | 擁塞窗口(cwnd) | 滑動窗口(Window字段) |
觸發信號 | 丟包、延遲增加 | 接收方通告的窗口大小 |
七、關鍵參數與公式
實際發送窗口:
Window=min?(cwnd,rwnd)Window=min(cwnd,rwnd)RTT估算:
SRTT=α×SRTT+(1?α)×NewRTTSRTT=α×SRTT+(1?α)×NewRTT
(α通常為0.875,平滑波動)
八、現代改進方向
BBR(Bottleneck Bandwidth and RTT):
Google提出的算法,基于帶寬和延遲探測,替代基于丟包的擁塞控制。
AQM(主動隊列管理):
路由器主動丟棄/標記報文(如RED算法),提前避免擁塞。
總結
TCP擁塞控制通過慢啟動、擁塞避免、快速重傳/恢復的動態調整,在公平性與高效性之間取得平衡。其核心是通過cwnd的增減響應網絡狀態,確保網絡在高負載下仍能穩定運行。