TCP原理 粘包分包現象

參考:
雲棲社區:就是要你懂 TCP– 最經典的TCP性能問題

粘包現象產生的原因

由於TCP協議本身的機制(三次握手)客戶端與服務器會維持一個連接(Channel),數據在連接不斷開的情況下,可以持續不斷地將多個數據包發往服務器,但是如果發送的網絡數據包太小,那麼他本身會啓用Nagle算法(可配置是否啓用)對較小的數據包進行合併(基於此,TCP的網絡延遲要UDP的高些)然後再發送(超時或者包大小足夠)。

客戶端Send:hello
客戶端Send:csdn
服務端Recv:hellocsdn

多個數據包被合併在一起發送。客戶端發送兩次數據,服務端只響應一次接收。

分包現象產生的原因

  • 可能是IP分片傳輸導致的。
  • 可能是傳輸過程中丟失部分包導致出現的半包 。
  • 可能是一個包可能被分成了兩次傳輸,在取數據的時候,先取到了一部分。
  • 還可能與接收的緩衝區大小有關係。

客戶端Send:hellocsdn
服務端Recv:hello
服務端Recv:csdn

 一個數據包被分成了多次接收。客戶端發送一次數據,服務端收到兩個包。

粘包與分包的解決辦法

  • 一個是採用分隔符的方式,即我們在封裝要傳輸的數據包的時候,採用固定的符號作爲結尾符(數據中不能含結尾符),這樣我們接收到數據後,如果出現結尾標識,即人爲的將粘包分開,如果一個包中沒有出現結尾符,認爲出現了分包,則等待下個包中出現後 組合成一個完整的數據包,這種方式適合於文本傳輸的數據,如採用/r/n之類的分隔符;

  • 另一個是採用在數據包中添加長度的方式,即在數據包中的固定位置封裝數據包的長度信息(或可計算數據包總長度的信息),服務器接收到數據後,先是解析包長度,然後根據包長度截取數據包(此種方式常出現於自定義協議中),但是有個小問題就是如果客戶端第一個數據包數據長度封裝的有錯誤,那麼很可能就會導致後面接收到的所有數據包都解析出錯(由於TCP建立連接後流式傳輸機制),只有客戶端關閉連接後重新打開纔可以消除此問題,可以在處理這個問題的時候對數據長度做校驗,會適時的對接收到的有問題的包進行人爲的丟棄處理(客戶端有自動重發機制,故而在應用層不會導致數據的不完整性);

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