1. 程式人生 > >網絡學習筆記(二):TCP可靠傳輸原理

網絡學習筆記(二):TCP可靠傳輸原理

不必要 不一定 網絡學習 建立 位置 arq協議 四種 數據碎片 cnblogs

??TCP數據段作為IP數據報的數據部分來傳輸的,IP層提供盡最大努力服務,卻不保證數據可靠傳輸。TCP想要提供可靠傳輸,需要采取一定的措施來讓不可靠的傳輸信道提供可靠傳輸服務。比如:出現差錯時,讓發送方重傳數據;接收方來不及處理數據時,讓發送方降低傳輸速度。

一、數據流傳輸方式

??TCP傳輸的數據一般分為兩類:交互數據、成塊數據。交互數據一般較小,比如發送1個字節的交互數據,加上TCP數據段首部以及IP數據報首部,至少需要41個字節。在廣域網,數量眾多的交互數據會增加擁塞出現的可能。而成塊數據的報文段基本上都是滿長度的。

??根據不同情況,兩種數據流采用不同的傳輸方式。

1、交互數據流傳輸

??在互聯網早期,通信鏈路並不可靠,因此在鏈路層傳輸數據時要采用可靠的傳輸協議,其中最簡答的協議叫“停止等待協議”。在運輸層並不使用停止等待協議,只是傳輸交互數據流傳輸時采用的nagle算法和該協議的原理很類似。

(一)、停止等待ARQ協議

??“停止等待”是指每發送完一個分組就停止發送,等待對方確認,在收到對方確認後再發送下一個分組。發送方在一定時間沒有收到確認,則會重傳分組。

技術分享圖片
??如上圖所示,發送方發送數據分組A,接收方接收到A後,向發送方發送確認數據;發送方在收到A的確認後,繼續發送數據分組B。

??數組分組在傳輸過程中發生錯誤時有兩種情況:

1、當接收方收到錯誤數據分組時,會直接丟棄分組。


2、如果數組分組在傳輸的過程中丟失。

??在這兩種情況下,接收方都不會發送任何信息。發送方在一定時間內沒有收到確認,就認為分組丟失,然後重傳該數據分組,這就叫超時重傳

??停止等待ARQ協議就是通過這種確認和重傳的機制,在不可靠的網絡上實現可靠通信。

(二)、nagle算法

??在傳輸交互數據流時,一般采用nagle算法。nagle算法要求在一個TCP連接上最多只能有一個未被確認的小分組,在該分組的確認到達之前不能發送其他分組。值得註意的是:並不是在收到確認之後立刻發送其他分組,TCP連接上允許不存在數據分組。具體的nagle算法發送分組的規則如下:

1、緩存中的數據長度達到最大報文長度

時,則允許發送。

2、緩存中的數據長度達到發送窗口大小的一半時,則允許發送。

3、報文段首部FIN標誌位置為1,則允許發送。

4、報文段首部設置了TCP_NODELAY選項,則允許發送;

5、發生了超時(一般為200ms),則立即發送。

??TCP在未收到確認時收集這些零散的數據,當確認到達的時候,可以以一個報文段發送出去。確認到達的越快,數據發送的也就越快。

??nagle算法能夠有效解決交互類的小數據過多的問題,降低網絡擁塞出現的可能。但是由於不是將緩存中收到的數據立刻發送出去,因此會產生一定的時延。另外,接收方一般會延遲確認,以便將確認報文與要送的數據相結合起來,一般延遲時間為200ms。

??對於一些實時應用程序來說,nagle算法帶來的延遲是不能夠接受的。TCP標準規定,必須實現nagle算法,但也必須提供一種可以關閉nagle算法的方法。上述nagle算法規則中第四條說的TCP_NODELAY選項就是nagle算法被關閉的標誌。

2、成塊數據流傳輸

??成塊數據往往超過最大報文長度,要進行拆分之後再發送,交互數據碎片化的問題不會出現。成塊數據是通過基於滑動窗口協議來連續ARQ協議完成的。

(一)、滑動窗口協議

??使用基於停止等待協議的nagle算法的缺點是信道利用率太低。如下圖所示:

技術分享圖片
??如果使用流水線傳輸,那麽信道利用率會大幅提升。TCP采用滑動窗口協議來實現流水線傳輸。

技術分享圖片
??滑動窗戶協議是指數據發送方有一個發送窗口,發送窗口範圍內的數據允許發送,隨著接收方傳來的確認信息以及通知的接收窗口的大小來動態調整發送窗口的起始位置以及大小。

技術分享圖片
??如圖所示:序號1-4的數據是已經發送過並且被確認的數據,TCP可以將這些數據清出緩存;序號5-11是在窗口範圍內的數據,允許發送;序號12-16的數據在緩存中不允許發送。

??窗口後沿是由接收方發送的確認序號決定的,窗口前沿是由確認序號與發送窗口大小共同決定的。而發送窗口大小並一定等於接收方提供的接收窗口的大小,發送方會根據網絡擁塞情況來動態調整發送窗口大小,前提是發送方發送窗口大小一定不大於接收方接收窗口大小。

??窗口的滑動有三種情況:

1、前沿向右移動,這種情況發生在數據發送並被確認時。

2、後沿向右移動,允許發送更多數據。這種情況發生在接收窗口增大或者網絡擁塞情況緩解時。

3、後沿向左移動,這種情況發生在接收方希望發送窗口縮小時,TCP標準強烈不建議出現這種情況。因為發送方在收到縮小窗口的通知時,可能已經發送了一些縮小部分的數據,容易造成錯誤。

??窗口前沿無法向左移動,因為TCP會將窗口之外已經收到確認的數據清除出緩存。

??TCP要求接收方有累計確認功能,接收方不必立刻對收到的數據進行確認,這樣可以減少傳輸開銷。另外,在發送確認時也可以捎帶上接收方要發送的數據。TCP標準規定確認推遲的時間不能超過0.5秒,如果收到一個具有最大報文長度的報文段,則必須隔一個報文段就發送一個確認。

??累積確認功能使得接收方只對按序到達的最後一個分組發送確認,表示這個分組之前的分組已經全部到達。接收方不能夠準確的通知發送方已經發送到接收方的數據分組。

??例如,上圖中序號5、6、7、9、10分組到達接收方,接收方發送的確認序號是8,即接收方沒有收到序號8的分組,希望下次收到序號8的分組。而序號9、10分組雖然已經到達的事實,發送方並不知曉。

??這會導致一個問題:一旦發生超時重傳的情況,發送方是否需要再次發送已經到達的數據?如果不需要,又該如何獲知具體哪些數據已經到達?

??滑動窗口協議自動重傳請求技術結合形成連續ARQ協議連續ARQ協議根據超時重發數據方式的不同分為後退N幀ARQ協議選擇重發ARQ協議

(二)、後退N幀ARQ協議

??在發生超時重傳時,後退N幀ARQ協議不考慮確認序號之後的分組是否已經發送到接收方,直接從確認序號開始重傳之後的數據。

技術分享圖片
??如上圖所示:序號5、6、7、9、10分組到達接收方,確認序號為8。假如窗口大小不變,則窗口向右滑動,序號8-14在發送窗口中。超時重傳時不考慮序號9、10是否到達接收方,重傳序號8之後的全部在發送窗口的數據。

(三)、選擇重傳ARQ協議

??選擇重傳ARQ協議是指在接收方收到未按序排列的數據流時,通知發送方重傳缺失的數據,而不是重傳全部數據。TCP數據段首部中添加選擇確認選項SACK可以實現該目的。

技術分享圖片
??如圖所示,假設上述分組都在發送窗口中,收到三個不連續的分組。三個分組的邊界分別為:[4000,5001]、[6000,7001]、[8000,9001]。在建立TCP連接時,連接雙方先商定好,在首部選項中加入“允許SACK”的選項。在之後的TCP報文段中增加SACk選項,以便接收方向發送方報告不連續的字節塊的邊界。

??因為序號是32位,因此指明一個邊界需要4個字節,說明一個字節塊的邊界需要8個字節。另外需要一個字節指明是SACK選項,一個字節指明這個選項的大小。TCP報文段首部選項最大為40個字節,因此最多指明4個字節塊的邊界信息。

??TCP標準並未指明發送方應該如何響應SACK,因此大多數實現還是重傳所有未被確認的數據分組。

二、超時重傳時間

??對於每一個連接,TCP管理這4個不同的定時器:

1、重傳定時器:決定何時重傳未被確認的數據分組。

2、堅持定時器:使窗口大小信息保持不斷流動。

3、保活定時器:檢測空閑連接的另一端是否崩潰或重啟。

4、2MSL定時器:測量一個連接處於TIME_WAIT狀態的時間。

??在超時重傳的情況下,如果將超時重傳的時間設置的太短,會出現很多不必要的重傳,增大網絡負荷;如果設置的時間太長,則使網絡的空閑時間增大,降低傳輸效率。TCP采用一種自適應的算法來動態計算超時重傳的時間。

1、報文段往返時間

??一個報文段發出的時間與收到確認的時間只差就是報文段的往返時間RTT平滑的往返時間RTT_S是RTT的加權平均值。第一次測量時,RTT_S等於RTT的值,之後測量到新的RTT值時按以下公式計算:

新的RTT_S = (1 - α)×(舊的RTT_S)+ α ×(新的RTT樣本)

??TCP標準推薦α的值為0.125。

??RTT偏差的加權平均值RTT_D,與RTT_S和新的RTT樣本之差有關。第一次測量時,RTT_D的值取RTT的一半,之後的測量中采用如下公式:

新的RTT_D = (1 - β)×(舊的RTT_D)+ β × |RTT_S - 新的RTT樣本|

??TCP標準推薦β的值為0.25。

??超時計時器設置的超時重傳時間RTO由如下公式求得:

RTO = RTT_S + 4 × RTT_D

2、Karn算法

??在實際測量報文段往返時間RTT時會遇到一些問題,如下圖所示:

技術分享圖片
??發送報文段後,在一定時間內沒有收到確認。重傳該報文段,之後收到確認報文。那麽怎麽確定確認報文是對哪個報文的確認?因為重傳的報文和原報文完全相同,收到的確認報文也相同。那麽報文段往返時間RTT是A還是B呢?

??在上述情況下,Karn提出一個算法:在計算加權平均RTT_S時,只要報文段重傳了,就不采用其往返時間樣本。這樣的到的加權平均RTT_S和RTO就比較準確。

??Karn算法也存在問題:當報文段的時延突然增大很多時,在原重傳時間內不會收到確認報文,於是重傳該報文段。根據Karn算法,重傳的報文段往返時間不會被采用,因此超時重傳時間就無法更新。

??因此要對Karn算法進行修正:報文重傳時,就把超時重傳時間RTO增大一些。典型的做法是重傳時間變成原來的兩倍。當不再發生重傳時,再根據計算公式算出超時重傳時間。

三、流量控制

??通過TCP連接發送數據,如果發送方發送數據很慢,容易造成資源浪費;如果發送方發送數據過快,接收方來不及接收會造成數據丟失。流量控制就是指在接收方能夠接收的範圍內,合理而又快速的發送數據。

1、基於滑動窗口的流量控制

??利用滑動窗口機制可以實現對發送方的流量控制。在TCP連接建立時,接收方會在確認報文段中給出自己接收窗口的大小。在每次發送確認報文時能夠根據情況動態調整接收窗口的大小,並將告知發送方。如下圖所示:

技術分享圖片
??發送方發送序號從1開始的100字節的數據,接收方在確認報文中聲明自身的接收窗口大小為300字節。之後發送方發送300字節數據,接收方在確認報文中聲明自身接收窗口大小調整為50字節。發送方再發送50字節數據之後,收到接收方傳來的確認報文,在該報文中聲明接收窗口為0。

??在接收方接收窗口為0時,發送方不再發送數據,直到接收方發送確認報文表明窗口大小發生改變。可是這個確認報文不一定能夠被發送方接收到,如果一旦該確認報文丟失,雙方都將處於等待中,形成死鎖。為防止這種情況出現,TCP規定在收到對方接受窗口為0時,啟動一個堅持定時器周期性的發送探測報文,以確定對方接收窗口為0的狀態是否改變。

??另外,TCP標準規定:接收方接收窗口為0時,不再接收正常數據,但是可以接收零窗口探測報文段確認報文段攜帶緊急數據的報文段

2、糊塗窗口綜合癥

??糊塗窗口綜合癥是指僅僅有少量數據通過連接進行交換,而不是滿長度的報文段。這樣會導致網絡傳輸的效率很低。

??如果接收緩存已經存滿,此時接收方的應用程序每次只從接收緩存中讀取少量數據,則接收方的接收窗口會一直保持在一個較低的值,導致發送方每次只能發送少量數據,會導致糊塗窗口綜合癥

??如果發送方應用程序每次向發送緩存中寫入少量數據,TCP選擇每次收到數據之後立即發送,也會導致糊塗窗口綜合癥

??避免糊塗窗口綜合癥可以從兩端采取解決措施:

1、接收方不通告小窗口。通常的算法是接收方不通告一個比當前窗口大的窗口(可以為0),除非窗口可以增加一個報文段大小(也就是將要接收的MSS)或者可以增加接收方緩存空間
的一半,不論實際有多少。

2、 發送方在存在滿長度的報文段或者接收方通告窗口大小一半報文時才發送。

四、MSS

??最大報文段長度MSS是指每一個TCP報文段中數據字段的最大長度。數據字段長度加上首部長度就等於TCP報文段的長度。

??MSS是在建立TCP連接時通信雙方協商確定的。第一次握手時,發送方可以在首部中增加MSS選項,如果沒有MSS選項,則MSS默認為1460字節。第二次握手時,接收方也可以在選項中增加MSS選項,最終MSS的值取連接雙方聲明的MSS中最小值。

??如果數據鏈路層使用以太網的話,最大傳輸單元MTU為1500字節,IP數據報首部最少為20字節,TCP數據段首部至少為20字節,那麽MSS最大為1460字節。如果數據鏈路層使用互聯網,那麽MTU=576字節,MSS最大為536字節。

??在網絡層,如果傳輸的數據大於MTU,則會在發送端進行數據分片,然後再接收端的網絡層進行組合。如果其中任何一個分片產生錯誤,都會導致整個TCP報文段重傳。因此TCP會對數據進行分段,分段之後的數據往下交付不會超過MTU,可以避免網絡層對數據進行分片。在傳輸層,UDP不像TCP那樣進行數據分段,UDP會將應用程序交付下來的整個數據封成一個數據報,如果數據報大小超過MTU,則由網絡層進行分片。

五、擁塞控制

??擁塞控制是指防止過多的數據註入網絡中,這樣可以使網絡中路由器或者鏈路不致過載。現在通信線路的傳輸質量一般都很好,因傳輸出現差錯丟棄分組的概率很小。因此,判斷網絡擁塞的依據就是出現了超時

??TCP進行擁塞控制常用的算法有四種:慢啟動擁塞避免快重傳快恢復

1、慢啟動

??TCP為發送方維持一個擁塞窗口,記為cwnd。擁塞窗口是發送方使用的流量控制,接收方聲明的接收窗口是接收方使用的流量控制。發送方的發送窗口大小等於這兩個窗口中的最小值。

??擁塞窗口的值跟SMSS有關,SMSS為發送的最大報文段長度。舊的規定是擁塞窗口的初始值為1至2個SMSS,RFC 5681規定擁塞窗口的初始值不超過2至4個SMSS。具體規定如下:

1、若SMSS>2190字節,則cwnd=2×SMSS字節,且不得超過2個報文段。

2、若2190≥SMSS>1095字節,則cwnd=3×SMSS字節,且不得超過3個報文段。

3、若SMSS≥1095字節,則cwnd=4×SMSS字節,且不得超過4個報文段。

??慢啟動算法規定:擁塞窗口初始化後,每收到一個對新報文的確認,擁塞窗口就加一個SMSS的大小。擁塞窗口以字節為單位,但是慢啟動以SMSS大小為單位增加。按照慢啟動算法,經過一輪傳輸,擁塞窗口就增大一倍,這是一種指數增長的關系。

2、擁塞避免

??慢啟動算法除了維持擁塞窗口cwnd變量之外,還維持另一個變量慢啟動門限ssthresh。當cwnd以指數增長的形式增長到大於或等於ssthresh時,就不再采用慢啟動算法,而是采用擁塞避免算法來進行擁塞控制。

??擁塞避免算法規定:每次收到一個確認時將cwnd增加1/cwnd個SMSS。即不再是像慢啟動算法那樣經過一輪傳輸cwnd翻倍了,而是經過一輪傳輸增加一個SMSS。這是一種加性增長的關系。

??當擁塞發生時(超時或收到重復確認),cwnd被設置為1個SMSS。ssthresh被設置為當前窗口大小的一半,但最少為 2個報文段。

??例如:假設TCP的ssthresh的初始值為 8 SMSS。當擁塞窗口上升到 12 SMSS時網絡發生了超時,TCP使用慢開始和擁塞避免。擁塞窗口大小如下圖所示:

技術分享圖片

3、快重傳

??如果個別報文段在網絡中丟失,網絡並沒有發生擁塞,這種情況下發送方收不到確認報文,在超時之後會重傳該報文。發送方誤以為網絡發生擁塞,錯誤的啟動慢開始算法,降低了傳輸效率。

??采用快重傳算法可以讓發送方盡早知道個別報文段的丟失。快重傳算法要求接收方不要延時發送確認,即使收到失序的報文段也要立刻發送對已收到報文的重復確認。如下圖所示:

技術分享圖片
??接收方收到M1之後發送對M1的確認報文,M2報文丟失,之後接收方收到M3、M4、M5時每次都發送對M1報文的重復確認。快重傳算法規定當收到三次重復確認後,發送方就認為M2報文段丟失,立即重傳M2報文段,而不用等待超時時再重傳,這樣可以避免發送方誤認為網絡發生擁塞。使用快重傳可以使整個網絡的吞吐量提高約20%。

4、快恢復

??在快重傳算法執行後,發送方知道只是丟失個別報文,而不是網絡發生擁塞。之後並不會執行慢啟動算法,而是執行快恢復算法:調整門限值ssthresh = cwnd/2,同時設置cwnd = ssthresh + 3 SMSS。這種設置門限值為當前擁塞窗口的一般,同時根據門限值調整擁塞窗口的形式稱為乘法減小

??為什麽要設置擁塞窗口的值為門限值加3個報文段,而不是直接等於門限值?這是因為發送方收到三個確認報文,就認為有三個分組已經離開網絡到達接收方的緩存,這三個確認報文不再占用網絡資源,可以適當增大擁塞窗口的大小。

六、總結

??TCP數據流傳輸方式分為:交互數據流、成塊數據流。交互數據流采用nagle算法來控制流量,成塊數據流通過基於滑動窗口協議連續ARQ協議完成的。連續ARQ協議根據超時重傳時是重傳全部數據還是選擇性的重傳而分為:後退N幀ARQ協議選擇重傳ARQ協議

??超時重傳的時間是動態確定的,根據報文段往返時間經過改進後的Karn算法來計算的。

??流量控制就是指在接收方能夠接收的範圍內,合理而又快速的發送數據。發送方與接收方都要采取措施來防止糊塗窗口綜合癥情況的發生。

??最大報文段長度MSS是在建立連接時由雙方協商確定的,TCP數據報的MSS受限於網絡層的最大傳輸單元MTU。TCP會將應用程序交付的數據進行分段,每個報文段加上TCP報文段首部以及IP數據報首部不會超過MTU,這樣網絡層就不會對TCP數據段進行分片。UDP會將應用程序交付的數據打包成一個UDP數據報,分片任務由網絡層來完成。

??TCP進行擁塞控制常用的算法有四種:慢啟動擁塞避免快重傳快恢復。這四種算法一般都不是孤立使用的,慢啟動擁塞避免之間會根據擁塞窗口是否達到ssthresh以及是否發生重傳來切換;快重傳算法之後緊跟著使用快恢復算法。

如需轉載,煩請註明出處:https://www.cnblogs.com/lidengfeng/p/10538536.html

網絡學習筆記(二):TCP可靠傳輸原理