上一篇http://www.cnblogs.com/whc-uestc/p/4715334.html中已經講到TCP跟蹤一個擁塞窗口來(cwnd)提供擁塞控制服務,經過調節cwnd值以控制發送速率。那麼TCP如何基於丟包事件來設置cwnd值?經過TCP擁塞控制算法來實現。TCP擁塞控制算法主要有三部分:慢啓動、擁塞避免、快速恢復。html
一、慢啓動算法
當一條TCP鏈接開始時,cwnd的值通常初始設置爲MSS的較小值。由於只有當發送方接收到ACK,纔會更新cwnd的值,因此在一個RTT時間內,發送方只能發送cwnd字節大小的數據,這就使得初始發送速率大約爲MSS/RTT。這是一個較小的值,大部分的帶寬仍是空閒的,如何迅速更新cwnd以提升帶寬利用率??網絡
慢啓動狀態:cwnd的值以1個MSS開始而且每當傳輸的報文段首次被確認就增長一個MSS。spa
從上面的過程,不難發現每過一個RTT,發送速率就會翻一倍。雖然起始速率只有MSS/RTT,可是在慢啓動的過程當中是以指數增加的。固然,帶寬是有限的,發送速率不可能無限制地增加,那麼問題來了,何時結束這種指數增加??htm
(1) 當有一個超時引發的丟包事件(擁塞)時,TCP發送方將cwnd設置爲1並從新開始慢啓動過程;同時將慢啓動閾值ssthresh設置爲cwnd/2。blog
(2) 在(1)從新慢啓動過程當中,當cwnd的值增加到大於等於慢啓動閾值ssthresh時,慢啓動結束,同時轉移到擁塞避免模式。排序
(3) 若是在慢啓動的過程當中,發送方收到3個冗餘的ACK,TCP就結束慢啓動過程,執行快速重傳並進入快速恢復模式。事件
二、擁塞避免get
上面說到,只有當再次啓動慢啓動而且cwnd增加到大於等於慢啓動閾值ssthresh時,纔會進入擁塞避免模式,因此當進入到擁塞避免時,cwnd的值大概是在第一次遇到擁塞時的cwnd的值的一半。此時若是繼續進行慢啓動就會使cwnd的值翻倍從而可能致使擁塞。因此擁塞避免模式對於每次收到的ACK,並不像慢啓動那樣直接將cwnd增長一個MSS字節,而是增長MSS*MSS/cwnd字節。也就是說當MSS=1460字節,cwnd爲14600字節,那麼每次收到一個ACK,cwnd增長1460*1/10字節,只有收到10個ACK,cwnd纔會增長一個MSS。總結
問題來了,與慢啓動同樣,難道cwnd的值也是這麼一直增加下去麼??何時結束呢?
(1) 當有一個超時引發的丟包事件(擁塞)時,同慢啓動同樣,TCP發送方將cwnd設置爲1並從新開始慢啓動過程;同時將ssthresh設置爲cwnd/2。
(2) 當收到3個冗餘的ACK時,ssthresh設置爲cwnd/2,TCP將cwnd的值設置爲ssthresh+3,進入快速恢復模式。
三、快速恢復
對於引發TCP進入快速恢復狀態的缺失報文段,對收到的每一個冗餘ACK,cwnd的值增長1個MSS,當收到新的ACK時TCP把cwnd設置爲ssthresh的值後進入擁塞避免狀態。
當在快速恢復階段出現超時事件,cwnd的值被設置爲1個MSS,而且ssthresh的值設置爲cwnd的一半,進入慢啓動狀態。
TCP的擁塞控制實際上是加性增、乘性減(AIMD)的擁塞控制方式,當TCP鏈接的路徑上沒有擁塞(經過判斷丟包事件)時,發送速率加性增;當出現丟包事件時,發送速率乘性遞減。咱們知道UDP自己是沒有實現擁塞控制的,其實若是大量使用UDP而沒有任何約束,那麼網絡就很容易出現死鎖,使得端到端之間不多有數據可以被傳輸。
四、總結:
固然,雖然UDP是不可靠、無鏈接的傳輸層協議,而TCP是面向鏈接的提供可靠數據傳輸的傳輸層協議。可是UDP的應用依舊很廣,像DNS,QQ都是用的是UDP,不少人會奇怪,爲何TCP提供了那麼多服務,爲何不用TCP而用這麼不可靠的UDP呢??
其實不管TCP仍是UDP,在如此複雜的網絡中,並不多是徹底可靠的。
可是正由於TCP提供了這麼多的服務,使得TCP變得很臃腫,很難發送大容量的數據;這時候,輕量的傳輸層協議UDP就站出來了。UDP很簡單,不提供那麼多的機制和服務,使得UDP的傳輸速率能夠比TCP快不少。固然有人會說,UDP丟包率很高,UDP接收到無序的數據包,UDP沒有擁塞,可能致使網絡癱瘓等等一些問題。
由於傳輸層及以上的層次都是隻在端系統中實現的,在網絡分組交換機中只有網絡層一下的實現,也就是說TCP的全部這些服務都是基於端到端的服務。既然是端到端的服務,那麼上述的全部問題均可以經過上層(也就是應用層)來實現,經過在應用層把發送的數據進行編號,就能夠在接收端對接收的數據進行排序,從而的到有序的數據;經過在應用層添加確認和重傳,就能夠大大下降丟包率;經過在應用層加一個窗口,來達到流量控制和擁塞控制的目的。固然具體基於UDP的實現其實並不須要把因此TCP的服務都在應用層實現,不然還不如用TCP。咱們只須要實現那些咱們須要和關係的服務便可,好比說咱們須要下降丟包率,咱們就只實現重傳機制。(固然咱們也能夠徹底不用傳輸層,應用層直接經過網絡層通訊)
UDP很自由,能夠任由上層來實現;TCP很全面,能夠給上層提升可靠的數據傳輸和各類機制。到底選擇哪種傳輸層協議,其實還要根據具體的應用來選擇。存在既有價值,關鍵是各方面的權衡而已。
版權全部,歡迎轉載,轉載請註明出處。