TCP協議之如何保證傳輸的可靠性

一、問題

TCP協議之如何保證傳輸的可靠性?我們先看下TCP的頭部圖片和TCP頭部的字段

/*TCP頭定義,共20個字節*/
typedef struct _TCP_HEADER 
{
  short m_sSourPort;              // 源端口號16bit
  short m_sDestPort;             // 目的端口號16bit
  unsigned int m_uiSequNum;         // 序列號32bit
  unsigned int m_uiAcknowledgeNum;    // 確認號32bit
  short m_sHeaderLenAndFlag;        // 前4位:TCP頭長度;中6位:保留;後6位:標誌位
  short m_sWindowSize;            // 窗口大小16bit
  short m_sCheckSum;              // 檢驗和16bit
  short m_surgentPointer;          // 緊急數據偏移量16bit
} __attribute__((packed))TCP_HEADER, *PTCP_HEADER;

 

 

 

 

 

 

 

二、 保證可靠性的手段

1)、校驗和(只要協議的包頭裏面有校驗和都支持:比如TCP協議 UDP協議  IP協議)

校驗和:發送的數據段都當做一個16位的整數,將這些整數加起來。並且前面的進位不能丟棄,補在後面,最後取反,得到校驗和。 

 收方比對校驗和與發送方不一致,那麼數據一定傳輸有誤。但是如果接收方比對校驗和與發送方一致,數據不一定傳輸成功

 

 

 

 

 

 

 

2)、確認號與序列號(TCP協議包頭裏面分別是32位,序列號去掉服務端收到的重複數據)

序列號:TCP傳輸時將每個字節的數據都進行了編號,這就是序列號(通過序列號可以去重)
確認應答:TCP傳輸的過程中,每次接收方收到數據後,都會對傳輸方進行確認應答。也就是發送ACK報文。這個ACK報文當中帶有對應的確認序列號,告訴發送方,接收到了哪些數據,下一次的數據從哪裏發。

 

序列號的作用不僅僅是應答的作用,有了序列號能夠將接收到的數據根據序列號排序,並且去掉重複序列號的數據。這也是TCP傳輸可靠性的保證之一

 

 

 

 

 

3)、超時重傳

(1)、發送數據過程中爲什麼沒有客戶端沒有收到服務端返回的ACK的數據包

發送方發送一部分數據後,都會等待接收方發送的ACK報文,但是這時候發送方沒有收到ACK的數據包是怎麼回事?

  • 數據在傳輸過程中由於網絡原因等直接全體丟包,接收方根本沒有接收到(發送服務端中途丟包)
  • 收方接收到了響應的數據,但是發送的ACK報文響應卻由於網絡原因丟包了 (服務端收到包,返回客戶端丟包)

(2) 、重傳機制

TCP在解決這個問題的時候引入了一個新的機制,叫做超時重傳機制就是發送方在發送完數據後等待一個時間,時間到達沒有接收到ACK報文,那麼對剛纔發送的數據進行重新發送

如果是剛纔第一個原因,接收方收到二次重發的數據後,便進行ACK應答。

如果是剛纔第二個原因,接收方發現接收的數據已存在(判斷存在的根據就是序列號,所以上面說序列號還有去除重複數據的作用),那麼直接丟棄,仍舊發送ACK應答

(3)、重傳時間間隔

在Linux中(BSD Unix和Windows下也是這樣)超時以500ms爲一個單位進行控制,每次判定超時重發的超時時間都是500ms的整數倍。重發一次後,仍未響應,那麼等待2*500ms的時間後,再次重傳。等待4*500ms的時間繼續重傳。以一個指數的形式增長。累計到一定的重傳次數,TCP就認爲網絡或者對端出現異常,強制關閉連接。
 

 

 

 

4)、連接管理

就是三次握手與四次揮手的過程,可以看我的這篇博客 TCP之三次握手和四次揮手過程

 

 

 

 

5)、流量控制

我們知道實現流量控制是基於滑動窗口來實現的,請看我的這篇滑動窗口的博客 TCP之滑動窗口

 

 

 

6)、擁塞控制

TCP傳輸的過程中,發送端開始發送數據的時候,如果剛開始就發送大量的數據,那麼就可能造成一些問題。網絡可能在開始的時候就很擁堵,如果給網絡中在扔出大量數據,那麼這個擁堵就會加劇。擁堵的加劇就會產生大量的丟包,就對大量的超時重傳,嚴重影響傳輸。

所以TCP引入了慢啓動的機制,在開始發送數據時,先發送少量的數據探路。探清當前的網絡狀態如何,再決定多大的速度進行傳輸。這時候就引入一個叫做擁塞窗口的概念。發送剛開始定義擁塞窗口爲 1,每次收到ACK應答,擁塞窗口加 1。在發送數據之前,首先將擁塞窗口與接收端反饋的窗口大小比對,取較小的值作爲實際發送的窗口。

擁塞窗口的增長是指數級別的慢啓動的機制只是說明在開始的時候發送的少,發送的慢,但是增長的速度是非常快的。爲了控制擁塞窗口的增長,不能使擁塞窗口單純的加倍,設置一個擁塞窗口的閾值,當擁塞窗口大小超過閾值時,不能再按照指數來增長,而是線性的增長。在慢啓動開始的時候,慢啓動的閾值等於窗口的最大值,一旦造成網絡擁塞,發生超時重傳時,慢啓動的閾值會爲原來的一半(這裏的原來指的是發生網絡擁塞時擁塞窗口的大小),同時擁塞窗口重置爲 1。

擁塞控制是TCP在傳輸時儘可能快的將數據傳輸,並且避免擁塞造成的一系列問題。是可靠性的保證,同時也是維護了傳輸的高效性。

部分類容參考了博客:https://blog.csdn.net/liuchenxia8/article/details/80428157

 

 

發佈了1049 篇原創文章 · 獲贊 638 · 訪問量 290萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章