通常說來,咱們老是但願數據傳輸的更快一些。但若是發送方吧數據發送的過快,接收方就可能來不及接收,就會形成數據的丟失。所謂的流量控制就是讓發送方的發送速率不要太快,要讓接收方來的及接收。算法
設A向B發送數據。在鏈接創建是,B告訴了A:「個人接收窗口wnd=400」。所以,發送方的發送窗口不能超過接收方的給出的接收窗口的數值。請注意,TCP的窗口單位是字節,不是報文段。咱們應注意,接收方的主機B進行了三次流量控制。第一次把窗口減少到rwnd=300,第二次又減到rwnd=100,最後減到了rwnd=0,即不容許發送方再發送數據了。這種使發送方暫停發送的狀態將持續到主機B從新發出一個新的窗口值爲止。咱們還應注意到,B向A發送的三個報文段都設置了ACK=1,只有在ACK=1時確認好字段纔有意義。緩存
特別提示:TCP規定,SYN報文段不能攜帶數據,但要消耗一個序列號;SYN+ACK報文段也不能攜帶數據,一樣要消耗一個序列號;ACK報文段能夠攜帶數據,可是若是不攜帶數據則不消耗序列號。服務器
1.一、如今咱們考慮一種狀況,B向A發送了零窗口的報文段後不久,B的接收緩存又有了一些存儲空間。因而B向A發送了rwnd=400的報文段。然而這個報文段在傳送過程當中丟失了。A一直等待收到B發送的非零窗口的通知,而B也一直等待A發送的數據,若是沒有其餘措施,這種互相等待的死鎖局面將一直延續下去。網絡
爲了解決這個問題,TCP爲每個鏈接設有一個持續計時器,只要TCP鏈接的一方收到對方的零窗口通知,就啓動持續計時器。若持續計時器設置的時間到期,就發送一個零窗口探測報文段,僅攜帶一個字節的數據,而對方就在確認這個探測報文段時會給出如今的窗口值。若是窗口值仍爲0,那麼收到這個報文段的一方就從新設置持續計時器。若是窗口值不爲0,那麼死鎖的僵局就能夠打破了。性能
網絡擁塞每每是有許多的因素引發的。例如,當某個節點緩存的容量過小時,到達該節點的分組因存儲空間而不得不被丟棄。如今設想將該節點緩存的容量擴展到很是大,因而凡是到達該節點的分組都可在節點的緩存隊列中排隊,不受任何限制。因爲輸出鏈路的容量和處理機的速度並無獲得提升,所以在這隊列中的絕大多數的分組的排隊等待時間將會大大增長,結果是上層軟件只好把它們進行重傳,因而可知,簡單地擴大緩存的存儲空間一樣會形成網絡資源的嚴重浪費,於是解決不了網絡擁塞的問題。spa
猶如,處理機的速度太慢可能引發網絡的擁塞,簡單的將處理機的速度提升,可能會使得上述狀況緩解一些,但每每又會將瓶頸轉移到其餘的地方。問題的實質每每是整個系統的各個部分的不匹配。只有全部的部分都平衡了,問題纔會獲得解決。blog
2.一、擁塞控制與流量控制的關係隊列
所謂擁塞控制就是防止過多的數據注入到網絡中,這樣可使網絡中的路由器或鏈路不致過載。擁塞控制所要作的都有一個前提,就是網絡可以承受現有的網絡負荷。它是一個全局性的過程,涉及到全部的主機、全部的路由器,以及下降網絡傳輸性能有關的全部因素。資源
相反,流量控制每每指點對點通訊量的控制,是個端到端的問題。流量控制所要作的就是抑制發送端發送數據的速率,以便接收端來得及接收。路由
擁塞控制和流量控制之因此經常被弄混,是由於某些擁塞控制算法是向發送端發送控制報文,並告訴發送端,網絡已經出現麻煩,必須放慢發送速率。這點又和流量控制是很類似的。
1)慢開始
慢開始算法的思路是這樣的。當主機發送數據時,若是當即把大量數據字節注入到網絡,那麼就有可能引發網絡擁塞,由於如今並不清楚網絡的負荷狀況。經驗證實,較好的方法是先探測一下,即由小到大主鍵增大發送窗口,也就是說,有小到大逐漸增大擁塞窗口數值,一般在剛剛開始發送報文段時,先把擁塞窗口增長到多一個MSS的數值,用這樣的方法逐步增大發送飯的擁塞窗口cwnd,可使分組注入到網絡的速率更加合理。
2)擁塞避免算法的思路是讓擁塞窗口cwnd緩慢的增大,及每通過一個往返時間RTT就把發送方的擁塞窗口cwnd加1,而不是加倍。這樣,擁塞窗口cwnd按線性規律緩慢增加,比慢開始算法的擁塞窗口增加速率緩慢得多。
不管在慢開始仍是在擁塞避免階段,只要發送方判斷網絡出現擁塞,就是沒有按時收到確認,就要把慢開始門限ssthresh設置爲出現擁塞時的發送窗口值得一半,可是要不小於2,。而後把擁塞窗口cwnd從新設置爲,執行慢開始算法。這樣作的目的就是要迅速減小主機發送到網絡中的分組數,使得發生擁塞的路由器有足夠時間把隊列中積壓的分組處理完畢。
3)快重傳
快重傳算法首先要求接收方每收到一個失序的報文段後,就當即發出重複確認,爲的是可以及早知道有報文段沒有到達對方,而不要等待本身發送數據時才進行捎帶確認,快重傳算法規定,發送發只要一連收到3個重複的確認就應當當即重傳對方還沒有收到的報文段,而沒必要繼續等待爲丟失的報文段設置重傳計時器到期。
4)快恢復
與快重傳配合使用的還有快恢復算法,當發送方連續收到三個重複確認時,就執行乘法減少算法,把慢開始門限ssthresh減半。這是爲了預防網絡發生擁塞。請注意,接下去就再也不執行慢開始算法了。因爲發送方如今認爲網絡極可能沒有發生擁塞,所以與慢開始不一樣之處是如今不執行慢開始算法,即把擁塞窗口cwnd的值設置爲1,而是把cwnd值設置爲慢開始門限ssthresh減半後的數值,而後開始執行擁塞避免算法,使擁塞窗口慢慢的線性的增大。
3.一、實際應用中的例子:
爲何http下載不是直接以可以使用的最大速度下載而是一點一點地加快速度?若是直接以可以使用的最大速度下載會有什麼後果?
簡單說,當用戶向服務器創建鏈接時,沒人知道二者之間有效帶寬能有多大——多是1G的光纖,也多是坑爹的2G手機網絡……可採用的策略無非兩種:一是默認鏈路速率很大,一開始用能支持的最大流量發;發現對方接不過來再嘗試更小的流量;二是默認鏈路速率很小,用最低流量發;發完發現對方響應很快、沒有丟包,就嘗試加大速率發;沒丟再加大;若出現擁塞,切換到擁塞控制算法繼續嘗試,直到找到鏈路容許的最大速率。前者容易形成資源浪費,萬一存在網絡攻擊還會急劇放大攻擊的威脅能力;後者就好的多。不要被慢開始(slow start)這個名字給誤導了,它的意思是從低速開始試探流量,並非「慢慢增長下載速率」。其實相關算法要求儘快探明鏈路速率上限、同時還能應對各類意外狀況方爲最佳。