運作方法
TCP使用多種擁塞控制策略來避免雪崩式擁塞。TCP會為每條連線維護一個“擁塞視窗”來限制可能在端對端間傳輸的未確認分組總數量。這類似TCP流量控制機制中使用的滑動視窗。TCP在一個連線初始化或逾時後使用一種“慢啟動”機制來增加擁塞視窗的大小。它的起始值一般為最大分段大小(Maximum segment size,MSS)的兩倍,雖然名為“慢啟動”,初始值也相當低,但其增長極快:當每個分段得到確認時,擁塞視窗會增加一個MSS,使得在每次往返時間(round-trip time,RTT)內擁塞視窗能高效地雙倍增長。
當擁塞視窗超過慢啟動閾值(ssthresh)時,算法就會進入一個名為“擁塞避免”的階段。在擁塞避免階段,只要未收到重複確認,擁塞視窗則在每次往返時間內線性增加一個MSS大小。
擁塞視窗
在TCP中, 擁塞視窗(congestion window)是任何時刻內確定能被傳送出去的位元組數的控制因素之一,是阻止傳送方至接收方之間的鏈路變得擁塞的手段。他是由傳送方維護,通過估計鏈路的擁塞程度計算出來的,與由接收方維護的接收視窗大小並不衝突。
當一條連線創建後,每個主機獨立維護一個擁塞視窗並設定值為連線所能承受的MSS的最小倍數,之後的變化依靠線增積減機制來控制,這意味如果所有分段到達接收方和確認包準時地回到傳送方,擁塞視窗會增加一定數量。該視窗會保持指數增大,直到發生逾時或者超過一個稱為“慢啟動閾值(ssthresh)”的限值。如果傳送方到達這個閾值時,每收到一個新確認包,擁塞視窗只按照線性速度增加自身值的倒數。
當發生逾時的時候,慢啟動閾值降為逾時前擁塞視窗的一半大小、擁塞視窗會降為1個MSS,並且重新回到慢啟動階段。
系統管理員可以設定視窗最大限值,或者調整擁塞視窗的增加量,來對TCP調優。
在流量控制中,接收方通過TCP的“視窗”值(Window Size)來告知傳送方,由傳送方通過對擁塞視窗和接收視窗的大小比較,來確定任何時刻內需要傳輸的數據量。
慢啟動
慢啟動(Slow-start)是用於結合其他階段算法,來避免傳送過多數據到網路中而導致網路擁塞,算法在RFC5681中定義。
慢啟動初始啟動時設定擁塞視窗值(cwnd)為1、2、4或10個MSS。擁塞視窗在每接收到一個確認包時增加,每個RTT內成倍增加,當然實際上並不完全是指數增長,因為接收方會延遲傳送確認,通常是每接收兩個分段則傳送一次確認包。傳送速率隨著慢啟動的進行而增加,直到遇到出現丟失、達到慢啟動閾值(ssthresh)、或者接收方的接收視窗進行限制。如果發生丟失,則TCP推斷網路出現了擁塞,會試圖採取措施來降低網路負載。這些是靠具體使用的TCP擁塞算法來進行測量判斷。當達到慢啟動閾值(ssthresh)時,慢啟動算法就會轉換為線性增長的階段,算法控制每個RTT內擁塞視窗只增加1個分段量。雖然稱為“慢啟動”,但實際上比擁塞控制階段的視窗增加更為激進。
對於處理報文丟失這個事件上,不同擁塞控制算法表現有所不同:
•TCP Tahoe
•對於TCP Tahoe算法,當發生丟失時,會進入“快速重傳”機制,慢啟動閾值設為之前擁塞視窗值的一半,擁塞視窗值降為初始值,重新進入慢啟動階段。當擁塞視窗值達到慢啟動閾值時,每RTT內擁塞視窗增加值則為“MSS除以CWND”的值,所以擁塞視窗按線性速度增加。
•TCP Reno
•TCP Reno算法實現了一個名為“快速恢復”的機制,慢啟動閾值設為之前擁塞視窗值的一半,和作為新的擁塞視窗值,並跳過慢啟動階段,直接進入擁塞控制階段。
慢啟動假設分段的未確認是由於網路擁塞造成的,雖然大部分網路的確如此,但也有其他原因,例如一些鏈路質量差的網路,會導致分段包丟失。在一些網路環境,例如無線網路,慢啟動效率並不好。
慢啟動對於一些短暫的連線性能並不好,一些較舊的網頁瀏覽器會創建大量連續的短暫連結,通過快速開啟和關閉連結來請求獲得檔案,這使得大多數連結處於慢啟動模式,導致網頁回響時間差。所以現在新的網頁瀏覽器,會通過向特殊的伺服器,開啟一條連結來請求獲得全部的檔案,而避免頻繁新建大量短暫連結。不過這樣對一些非請求網站所提供的服務,例如廣告跟蹤腳本、社交分享功能腳本、網路分析腳本等,並不適用。
和式增加,積式減少
和式增加,積式減少(additive-increase/multiplicative-decrease,AIMD,這裡簡稱“線增積減”)是一種反饋控制算法,其包含了對擁塞視窗線性增加,和當發生擁塞時對視窗積式減少。多個使用AIMD控制的TCP流最終會收斂到對線路的等量競爭使用。
快速重傳
快速重傳(Fast retransmit)是對TCP傳送方降低等待重發丟失分段用時的一種改進。TCP傳送方在每傳送一個分段時會啟動一個逾時計時器,如果相應的分段確認沒在特定時間內被送回,傳送方就假設這個分段在網路上丟失了,需要重發。這也是TCP用來估計RTT的測量方法。
重複確認(duplicate cumulative acknowledgements,DupAcks)就是這個階段的基礎,其基於以下過程:如果接收方接收到一個數據分段,就會將該分段的序列號加上數據位元組長的值,作為分段確認的確認號,傳送回傳送方,表示期望傳送方傳送下一個序列號的分段。但是如果接收方提前收到更下一個序列號的分段——或者說接收到無序到達的分段,即之前期望確認號對應的分段出現接收丟失——接收方需要立即使用之前的確認號傳送分段確認。此時如果傳送方收到接收方相同確認號的分段確認超過1次,並且該對應序列號的分段逾時計時器仍沒逾時的話,則這就是出現重複確認,需要進入快速重傳。
快送重傳就是基於以下機制:如果假設重複閾值為3,當傳送方收到4次相同確認號的分段確認(第1次收到確認期望序列號,加3次重複的期望序列號確認)時,則可以認為繼續傳送更高序列號的分段將會被接受方丟棄,而且會無法有序送達。傳送方應該忽略逾時計時器的等待重發,立即重發重複分段確認中確認號對應序列號的分段。