tcp粘包和拆包問題,以及封包和解包方案


參考:

workerman (框架協議源碼)

https://blog.csdn.net/msdnwolaile/article/details/50769708 (tcp粘包問題經典分析)

https://wiki.swoole.com/#/learn?id=tcp粘包問題 (swoole文檔)

https://www.cnblogs.com/vipstone/p/14239160.html(粘包分包問題解決的3種思路)

粘包與拆包的概念

TCP是基於字節流的,只維護發送出去多少,確認了多少,並沒有維護消息與消息之間的邊界;

 

在TCP/IP協議中,由於傳輸層並不了解應用層數據的含義,發送端傳輸層可能會對應用層數據進行拆分或者合並,在接收端也同樣如此。由此而產生的問題就是常常會聽說的“粘包與拆包”的問題。

“粘包拆包”的問題在“短報文”和“一問一答”的場景下其實並不會出現。短報文是指報文長度遠小於MSS的情況,應用層的報文在TCP報文中完全可以放下。

另一方面,“一問一答”的通信模式可以保證報文會以單一的TCP包發送出去。在這兩個條件下都滿足時,我們不需要考慮“粘包拆包”問題。

反之,如果這兩個條件不同時滿足,就很可能會出現“粘包拆包”問題。

粘包的主要原因:

  • 發送方每次寫入數據 < 套接字(Socket)緩沖區大小;
  • 接收方讀取套接字(Socket)緩沖區數據不夠及時。

半包的主要原因:

  • 發送方每次寫入數據 > 套接字(Socket)緩沖區大小;
  • 發送的數據大於協議的 MTU (Maximum Transmission Unit,最大傳輸單元),因此必須拆包。

問題描述,上圖

解決方法有三種,具體如下:

1,發送端給每個數據包添加包首部,首部長度應該至少包含數據包的長度 ;

2,固定每次發送的報文長度,不夠用0補充;

3,約定好包的邊界,添加首部尾部標識,如特許字符;

關鍵方法

1,封包方法

2,解包方法

3,重要函數和字符

pack(format,arg):將參數打包成二進制字符串

unpack(format,arg):從二進制解析出字符串

ord() 返回字符的ASCII碼值

chr() ASCII碼值對應的字符,與ord互補
strlen:字符串長度 substr:從某個位置開始截取 strpos:特殊邊界字符判斷 trim/rtrim/ltrim:去除特殊邊界字符

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM