TCP協議做爲一個可靠的面向流的傳輸協議,其可靠性是由流量控制和滑動窗口協議保證,而擁塞控制則由控制窗口結合一系列的控制算法實現。算法
1、滑動窗口協議緩存
1. 「窗口」對應的是一段能夠被髮送者發送的字節序列,其連續的範圍稱之爲「窗口」;網絡
2. 「滑動」則是指這段「容許發送的範圍」是能夠隨着發送的過程而變化的,方式就是按順序「滑動」。在引入一個例子來講這個協議以前,我以爲頗有必要先了解如下前提:spa
-1. TCP協議的兩端分別爲發送者A和接收者B,因爲是全雙工協議,所以A和B應該分別維護着一個獨立的發送緩衝區和接收緩衝區,因爲對等性(A發B收和B發A收),咱們以A發送B接收的狀況做爲例子;
-2. 發送窗口是發送緩存中的一部分,是能夠被TCP協議發送的那部分,其實應用層須要發送的全部數據都被放進了發送者的發送緩衝區;
-3. 發送窗口中相關的有四個概念:已發送並收到確認的數據(再也不發送窗口和發送緩衝區以內)、3d
已發送但未收到確認的數據(位於發送窗口之中)、blog
容許發送但還沒有發送的數據以、隊列
發送窗口外發送緩衝區內暫時不容許發送的數據;
-4. 每次成功發送數據以後,發送窗口就會在發送緩衝區中按順序移動,將新的數據包含到窗口中準備發送;
TCP創建鏈接的初始,B會告訴A本身的接收窗口大小,好比爲‘20’:進程
字節31-50爲發送窗口
路由
A發送11個字節後,發送窗口位置不變,B接收到了亂序的數據分組:io
只有當A成功發送了數據,即發送的數據獲得了B的確認以後,纔會移動滑動窗口離開已發送的數據;
同時B則確認連續的數據分組,對於亂序的分組則先接收下來,避免網絡重複傳遞:
2、流量控制
流量控制方面主要有兩個要點須要掌握。一是TCP利用滑動窗口實現流量控制的機制;二是如何考慮流量控制中的傳輸效率。
1. 流量控制
所謂流量控制,主要是接收方傳遞信息給發送方,使其不要發送數據太快,是一種端到端的控制。主要的方式就是返回的ACK中會包含本身的接收窗口的大小,而且利用大小來控制發送方的數據發送:
這裏面涉及到一種狀況,若是B已經告訴A本身的緩衝區已滿,因而A中止發送數據;等待一段時間後,B的緩衝區出現了富餘,因而給A發送報文告訴A個人rwnd大小爲400,可是這個報文不幸丟失了,因而就出現A等待B的通知||B等待A發送數據的死鎖狀態。爲了處理這種問題,TCP引入了持續計時器(Persistence timer),當A收到對方的零窗口通知時,就啓用該計時器,時間到則發送一個1字節的探測報文,對方會在此時迴應自身的接收窗口大小,若是結果仍未0,則重設持續計時器,繼續等待。
2. 傳遞效率
一個顯而易見的問題是:單個發送字節單個確認,和窗口有一個空餘即通知發送方發送一個字節,無疑增長了網絡中的許多沒必要要的報文(請想一想爲了一個字節數據而添加的40字節頭部吧!),因此咱們的原則是儘量一次多發送幾個字節,或者窗口空餘較多的時候通知發送方一次發送多個字節。對於前者咱們普遍使用Nagle算法,即:
*1. 若發送應用進程要把發送的數據逐個字節地送到TCP的發送緩存,則發送方就把第一個數據字節先發送出去,把後面的字節先緩存起來;
*2. 當發送方收到第一個字節的確認後(也獲得了網絡狀況和對方的接收窗口大小),再把緩衝區的剩餘字節組成合適大小的報文發送出去;
*3. 當到達的數據已達到發送窗口大小的一半或以達到報文段的最大長度時,就當即發送一個報文段;
對於後者咱們每每的作法是讓接收方等待一段時間,或者接收方得到足夠的空間容納一個報文段或者等到接受緩存有一半空閒的時候,再通知發送方發送數據。
3、擁塞控制
網絡中的鏈路容量和交換結點中的緩存和處理機都有着工做的極限,當網絡的需求超過它們的工做極限時,就出現了擁塞。擁塞控制就是防止過多的數據注入到網絡中,這樣可使網絡中的路由器或鏈路不致過載。經常使用的方法就是:
1. 慢開始、擁塞控制
2. 快重傳、快恢復
一切的基礎仍是慢開始,這種方法的思路是這樣的:
-1. 發送方維持一個叫作「擁塞窗口」的變量,該變量和接收端口共同決定了發送者的發送窗口;
-2. 當主機開始發送數據時,避免一會兒將大量字節注入到網絡,形成或者增長擁塞,選擇發送一個1字節的試探報文;
-3. 當收到第一個字節的數據的確認後,就發送2個字節的報文;
-4. 若再次收到2個字節的確認,則發送4個字節,依次遞增2的指數級;
-5. 最後會達到一個提早預設的「慢開始門限」,好比24,即一次發送了24個分組,此時遵循下面的條件斷定: cwnd_擁塞窗口 ssthresh_慢啓動閾值
*1. cwnd < ssthresh, 繼續使用慢開始算法;
*2. cwnd > ssthresh,中止使用慢開始算法,改用擁塞避免算法;
*3. cwnd = ssthresh,既可使用慢開始算法,也可使用擁塞避免算法;
-6. 所謂擁塞避免算法就是:每通過一個往返時間RTT就把發送方的擁塞窗口+1,即讓擁塞窗口緩慢地增大,按照線性規律增加(由指數增加轉爲線性增加);
-7. 當出現網絡擁塞,好比丟包時,將慢開始門限設爲原先的一半,而後將cwnd設爲1,執行慢開始算法(較低的起點,指數級增加);
上述方法的目的是在擁塞發生時循序減小主機發送到網絡中的分組數,使得發生擁塞的路由器有足夠的時間把隊列中積壓的分組處理完畢。慢開始和擁塞控制算法經常做爲一個總體使用,
而快重傳和快恢復則是爲了減小由於擁塞致使的數據包丟失帶來的重傳時間,從而避免傳遞無用的數據到網絡。快重傳的機制是:
-1. 接收方創建這樣的機制,若是一個包丟失,則對後續的包繼續發送針對該包的重傳請求;
-2. 一旦發送方接收到三個同樣的確認,就知道該包以後出現了錯誤,馬上重傳該包;
-3. 此時發送方開始執行「快恢復」算法:
*1. 慢開始門限減半;
*2. cwnd設爲慢開始門限減半後的數值;
*3. 執行擁塞避免算法(高起點,線性增加);