網絡基礎 -- 保證TCP協議可靠傳輸和提高性能的機制

目錄

保證TCP可靠傳輸的機制

1. 面向連接

2. 包序管理和確認應答

3. 超時重傳機制

4. 滑動窗口機制

5. 快速重傳機制

6. 擁塞窗口

7. 保活機制

提高傳輸性能的機制

1. 延遲應答機制

2. 捎帶應答機制


保證TCP可靠傳輸的機制

TCP協議是有連接, 面向字節流的, 可靠傳輸協議, 可靠性主要由以下機制保證.

1. 面向連接

先建立連接, 在進行通信, 面向連接需要三次握手, 保證通信雙方都具有數據收發的能力.

戳鏈接( ̄︶ ̄)↗ : 三次握手過程

2. 包序管理和確認應答

包序管理

依託於 TCP協議首部中的序號字段和確認序號字段實現, 具體來說, TCP將所要傳送的整個應用層報文(當應用層報文較大時, 可能要嵌在多個TCP報文段中發送)看成是一個個字節組成的數據流, 然後從頭開始對每一個字節編一個序號, 在建立連接時(三次握手時), 雙方要商定一個初始序號. TCP就將每一次所傳送的報文段中的第一個數據字節的序號放在TCP首部的序號seq字段中.

簡而言之, TCP每一次發送的都是有序好的, 所以收到的數據就不會因爲網絡延遲等原因而出現亂序現象.

確認應答

和包序管理一樣也依託於TCP協議首部中的序號字段和確認序號字段, 也依託於實現了包序管理.

簡單來說, 就是接收方對於接收到的每一條數據都要進行確認回覆(ACK), 告訴發送方, 接收方已經成功的收到了數據, 並且希望收到下一條報文的序列號是什麼

具體來說, TCP的確認應答是對接收到的數據的最高序號(即收到的數據流中的最後一個字節的序號) 表示確認.  但返回的確認序號是已收到的數據的最高序號加1. 也就是說, 確認序號表示期望下次收到的第一個數據字節的序號. 確認應答具有 "累計確認" 的效果.
(累計確認 : 當接收方連續收到多個TCP數據段, 接收方會按照序號進行接收, 相對應接收方也會發送多個應答報文給發送方, 但如果這些應答報文只有確認序號最大的一個報文被髮送方接收到,  那麼發送方就可以認定, 之前發的數據接收方也都收到了. 如下圖:

 

len爲數據長度, 圖中發送方連續發送三條數據, 接收方收到之後也確認應答了3次, 不過前兩次的確認應答丟失了, 發送方並沒有收到, 但接收方收到了最後一個應答, 那麼發送方就能確定之前的數據接收方也收到了.

        由於TCP能提供全雙工通信, 因此通信中的每一方都不必專門發送確認報文段, 而可以在傳送數據是順便把確認信息燒到傳送. 這樣可以提高傳輸效率.


3. 超時重傳機制

TCP協議是一種面向連接的可靠的傳輸層協議, 它保證了數據的可靠傳輸, 對於超時丟包等問題TCP設計的超時重傳機制. 其基本原理:在發送一個數據之後,就開啓一個定時器,若是在這個時間內沒有收到發送數據的ACK確認報文,則對該報文進行重傳,在達到一定次數還沒有成功時放棄併發送一個復位信號(RST包), 要求重新建立連接.

比較關鍵的是超時重傳的等待時間(定時器的時間RTO), 怎樣設置這個RTO, 從而保證對網絡資源最小的浪費. 如果RTO太小, 可能有些報文只是遇到擁堵或網絡不好延遲較大而已, 數據就會發生重傳, 這樣就會造成不必要的重傳. 太大的話, 使發送端需要等待過長的時間才能發現數據丟失, 影響網絡傳輸效率.  由於不同的網絡情況不一樣, 不可能設置一樣的RTO, 實際中RTO是根據網絡中的RTT(傳輸往返時間)來自適應調整的.  


4. 滑動窗口機制

TCP協議是支持發送方一次發送多條數據, 但要是發的較多, 接收方的接收緩衝區滿了, 那麼之後發送的數據也會丟失. 造成傳輸的不可靠. 所以, 又引入了滑動窗口機制.

滑動窗口機制依託於TCP協議首部中的窗口大小字段來實現發送方連續發送多條數據, 並且進行流量控制.

在三次握手建立連接時, 通信雙方會通過選項數據協商MSS(最大數據大小 -- 一條報文中的數據最大大小), 例如客戶端和服務端三次握手, 雙方各自都會將自己的MSS發送給對方, 最終取最小的一個MSS值作爲雙方通信的MSS. 

圖片來源於網絡
  • 發送方窗口大小取決於接收方的接收緩衝區中剩餘空間的大小 : 不能大於接收緩衝區中剩餘空間的大小
  • 發送方通過維護一個窗口前沿. 一個窗口後沿, 一個當前發送位置來維護一個窗口, 這個窗口內的數據就可以連續發送
  • 接收方通過自己接收緩衝區的大小, 也維護着一個窗口前沿, 一個窗口後沿和當前接收位置來維護着一個窗口
  • 發送方窗口後沿的移動 : 取決於是否收到接收方發送的後沿數據的確認回覆
  • 發送方窗口前沿的移動 : 取決於收到的確認應答中窗口大小字段, 因爲發送方的窗口的前沿減後沿不能大於接收方確認應答中的窗口大小
  • 接收方窗口後沿的移動 : 取決於是否收到發送方的後沿數據
  • 接收方窗口前沿的移動 : 取決於接收緩衝區中剩餘空間的大小(用戶通過recv()將數據取出去, 緩衝區就變大了)
圖片來源於網絡

5. 快速重傳機制

前面說到了超時重傳機制, 但這種機制還是存在一些問題, 例如 :

  • 發送方發送一個數據, 這個報文丟失了, 發送方接收不到接收方的確認應答, 在等待一個超時週期之後, 會進行重傳, 這就增加了時延.
  • 若發送方連續發送了多個數據, 但前面有一條數據丟失了, 因爲有一條數據丟失, 這條數據之後的數據都不能進行確認應答, 只能等待發送方超時重傳這些數據(丟失數據以及之後的所有數據), 超時等待時間較長.

此時TCP中又引入了快速重傳機制, 依託於滑動窗口機制實現.

具體來說, 當發送方;連續發送多條數據, 但接收方在接收時沒有接收到第一條, 卻已經收到了第二條數據, 接收方有理由認爲第一條數據已經丟了, 接收方就給發送方連續發送3次(間隔很短時間)第一條數據的重傳請求, 當發送方接收到三次某條數據的重傳請求, 求重傳這條數據. 爲什麼接收方要發送三次請求? 因爲要避免請求重傳的這條數據是因爲網絡延遲而沒有來(可能還會接收到), 可能會在接收方發送了兩次重傳請求後收到了這條數據, 那麼接收方就不再發送重傳請求, 而是發送確認應答.
(三次請求重傳時間  < 發送方的超時重傳時間)

                                      

在滑動窗口機制中,  數據丟失到底重傳哪些數據?

滑動窗口機制中有一次按協議 :

停等協議 : 針對網絡狀況不好的情況, 收到回覆纔會發送下下一條數據()

選擇重傳協議 : 哪條丟失重傳哪條. (缺點 : 需要接收方有更大的緩衝區)

回退n步協議 : 從丟失的那條開始, 後面數據全部都要重傳 .(缺點, 可能會造成大量數據重發)


6. 擁塞窗口

滑動窗口機制實現了數據的連續大量發送, 但若在通信時, 不瞭解網絡狀況而直接發送大量數據, 可能會造成大量數據丟包, 因此發送方總是維護着一個擁塞窗口進行擁塞控制, 擁塞窗口的大小取決於網絡的擁塞程度,並且動態地在變化. 實現網絡探測, 避免因爲網絡不好而造成的大量丟包.

圖片來源於網絡

 

發送方控制擁塞窗口的原則是:只要網絡沒有出現擁塞,擁塞窗口就再增大一些,以便把更多的分組發送出去. 但只要網絡出現擁塞, 擁塞窗口就減小一些, 以減少注入到網絡中的分組數.

慢開始算法: 每經過一個傳輸輪次,擁塞窗口大小cwnd 就加倍. 一個傳輸輪次所經歷的時間其實就是往返時間RTT. 不過“傳輸輪次”更加強調:把擁塞窗口cwnd所允許發送的報文段都連續發送出去,並收到了對已發送的最後一個字節的確認. 此外 ,"慢" 並不是指擁塞窗口大小(cwnd)增大速度慢, 而是指起點低, 起始擁塞窗口大小(cwnd) = 1, 使得發送方在開始時只發送一個報文段 (目的是試探一下網絡的擁塞情況), 然後再增大cwnd.

慢開始門限ssthresh : 爲了防止擁塞窗口cwnd增長過大引起網絡擁塞,還需要設置一個慢開始門限ssthresh狀態變量

  •     當 cwnd < ssthresh 時,使用上述的慢開始算法.
  •     當 cwnd > ssthresh 時,停止使用慢開始算法而改用擁塞避免算法.
  •     當 cwnd = ssthresh 時,既可使用慢開始算法,也可使用擁塞避免算法.

擁塞避免算法:讓擁塞窗口cwnd緩慢地增大,即每經過一個往返時間RTT就把發送方的擁塞窗口cwnd加1,而不是加倍。這樣擁塞窗口cwnd按線性規律緩慢增長,比慢開始算法的擁塞窗口增長速率緩慢得多.

注意 : “擁塞避免”並非指完全能夠避免了擁塞. 利用以上的措施要完全避免網絡擁塞還是不可能的. “擁塞避免”是說在擁塞避免階段將擁塞窗口控制爲按線性規律增長,使網絡比較不容易出現擁塞. 


7. 保活機制

TCP保活機制是一種在不影響數據流內容的情況下探測對方的方式. 它由一個保活計時器實現,當計時器被激發,連接一端將發送一個保活探測(簡稱保活)報文,另一端接收報文的同時會發送一個ACK作爲響應.

服務器每收到一次客戶端的請求後都會重新復位這個計時器,時間通常是設置爲7200s(默認), 即2小時, 若兩小時還沒有收到客戶端的任何數據,服務器就會每隔75秒(默認)發送一個探測報文段, 若一連發送9(默認)個探測報文, 客戶端仍然沒反應,服務器就認爲客戶端出了故障, 斷開連接,上層(應用層)體現, recv()返回0, send()觸發異常.

保活機制存在的問題:

  • 1. 短暫的網絡錯誤中,保活機會致使TCP斷開連接
  • 2. 保活機制佔用不必要的帶寬
  • 3. 按流量計費的網絡會花更多的錢

所以保活機制存在爭議, 許多人認爲這一功能不應該在TCP協議中提供,而應在應用程序中實現;反之也有人認爲大多數應用程序需要該功能,應該在TCP協議中實現。然後...現在所有主流TCP版本都實現了保活功能,只是該功能在默認情況下是關閉的,是一個可選擇激活的功能。


提高傳輸性能的機制

1. 延遲應答機制

數據傳輸的時候,發送方給接收方發送數據,接收方給發送方發去確認應答信息, 這樣每條數據都確認比較耗時, 效率低下, 並且立即確認應答會造成接收方窗口變小, 因爲收到的數據還沒有recv出去, 接收緩衝區剩餘空間變小, 造成吞吐率降低.  延遲應答就是接收方收到數據之後, 稍微等待一會再應答, 這樣可以提高數據的傳輸效率, 因爲發送方發送多條數據之後, 接收方只需要一次來確認應答, 這樣可以降低網絡擁塞的概率.  在接收方等待期間可能會因爲recv()而導致接收緩衝區變大, 窗口可能會較之前不變或變大, 保證吞吐率.

2. 捎帶應答機制

每一條確認應答都是一條數據, 至少需要一個TCP報頭, 爲了減少這種純報頭的數據, 會將這次確認應答報頭和即將要發送的數據合成一個數據發送, 確認應答數據被捎帶發送了.

舉個栗子 :

沒有捎帶應答機制 : 

甲 : 好久不見

乙 : 好久不見

乙 : 你又胖了

有捎帶應答機制 : 

甲 : 好久不見

乙 : 好久不見, 你又胖了

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章