TCP粘包問題

TCP粘包

TCP粘包是指發送方發送的若干包數據到接收方接收時粘成一包,從接收緩衝區看,後一包數據
的頭緊接着前一包數據的尾。        

1.出現原因

這裏提一下保護消息邊界和流,

保護消息邊界,就是指傳輸協議把數據當作一條獨立的消息在網上傳輸,接收端只能接收獨立的消息。也就是說存在保護消息邊界,接收端一次只能接收發送端發出的一個數據包。
面向流則是指無保護消息保護邊界的,如果發送端連續發送數據,接收端有可能在一次接收動作中,會接收兩個或者更多的數據包。

在流傳輸中出現,UDP不會出現粘包,因爲它有消息邊界,每條消息也是獨立的。

TCP字節流中,
1發送端需要等緩衝區滿才發送出去,造成粘包;

2接收方不及時接收緩衝區的包,造成多個包接收。
這裏寫圖片描述

具體如下:

(1)發送方引起的粘包是由TCP協議本身造成的,TCP爲提高傳輸效率,發送方往往要收集到足夠多的數據後才發送一包數據。若連續幾次發送的數據都很少,通常TCP會根據優化算法把這些數據合成一包後一次發送出去,這樣接收方就收到了粘包數據。

(2)接收方引起的粘包是由於接收方用戶進程不及時接收數據,從而導致粘包現象。這是因爲接收方先把收到的數據放在系統接收緩衝區,用戶進程從該緩衝區取數據,若下一包數據到達時前一包數據尚未被用戶進程取走,則下一包數據放到系統接收緩衝區時就接到前一包數據之後,而用戶進程根據預先設定的緩衝區大小從系統接收緩衝區取數據,這樣就一次取到了多包數據。

粘包情況有兩種,
一種是粘在一起的包都是完整的數據包:

這裏寫圖片描述

另一種情況是粘在一起的包有不完整的包:
這裏寫圖片描述


解決方法:

爲了避免粘包現象,可採取以下幾種措施:

(1)對於發送方引起的粘包現象,用戶可通過編程設置來避免,TCP提供了強制數據立即傳送的操作指令push,TCP軟件收到該操作指令後,就立即將本段數據發送出去,而不必等待發送緩衝區滿;
這裏寫圖片描述

PSH標誌:提示終端應用程序應該立即從TCP接收緩衝區讀走數據,爲接受後續數據騰出空間(如果應用程序不將接收到的數據讀走,它們就會一直停留在TCP接收緩衝區中)。

(2)對於接收方引起的粘包,則可通過優化程序設計、精簡接收進程工作量、提高接收進程優先級等措施,使其及時接收數據,從而儘量避免出現粘包現象;

(3)由接收方控制,將一包數據按結構字段,人爲控制分多次接收,然後合併,通過這種手段來避免粘包。

以上提到的三種措施,都有其不足之處。

(1)第一種編程設置方法雖然可以避免發送方引起的粘包,但它關閉了優化算法,降低了網絡發送效率,影響應用程序的性能,一般不建議使用。

(2)第二種方法只能減少出現粘包的可能性,但並不能完全避免粘包,當發送頻率較高時,或由於網絡突發可能使某個時間段數據包到達接收方較快,接收方還是有可能來不及接收,從而導致粘包。

(3)第三種方法雖然避免了粘包,但應用程序的效率較低。

TCP無保護消息邊界的解決

針對這個問題,一般有3種解決方案:

(1)發送固定長度的消息

(2)把消息的尺寸與消息一塊發送

(3)使用特殊標記來區分消息間隔

參考資料: 《Linux高性能服務器編程》
參考博客: https://www.cnblogs.com/kex1n/p/6502002.html

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