程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> Socket解決粘包問題1,socket解決粘包

Socket解決粘包問題1,socket解決粘包

編輯:C#入門知識

Socket解決粘包問題1,socket解決粘包


  粘包是指發送端發送的包速度過快,到接收端那邊多包並成一個包的現象,比如發送端連續10次發送1個字符'a',因為發送的速度很快,接收端可能一次就收到了10個字符'aaaaaaaaaa',這就是接收端的粘包。

  可能我們在平時練習時沒覺的粘包有什麼危害,或者通過把發送端發送的速率調慢來解決粘包,但在實時通信中,發送端常常是單片機或者其他系統的信息采集機,它們的發送速率是無法控制的,如果不解決接收端的粘包問題,我們無法獲得正常的信息。

  就以我自己正在做的項目來說,接收端是一台單頻指標測量儀,它會把當前測量的單頻指標信息通過socket接口發送給服務器,發送包長度約100字節,1s能發送10個包左右,如果我不實時處理粘包,為前台就無法實時展示采集到的單頻指標信息。

  下面演示的通信是在之前的框架基礎上增加的一些代碼,首先先創建一個包模擬類生成類PackageBuilder,它可以自動生成長度不一的包,用於測試發送,代碼如下,因為與通信無關所以對裡面的代碼不做說明。

public static class PackageBuilder { static StringBuilder package = new StringBuilder(); public static string[] BuildPackage(int count) { Random random = new Random(); int dataLength; string[] packageArr = new string[count]; int myChar; for (int j = 0; j < count; j++) { dataLength = random.Next(25) + 25; package.Append("HEAD|H1|"+dataLength); package.Append("data:"); for (int i = 0; i < dataLength-5; i++) { myChar = random.Next(26) + 65; package.Append((char)myChar); } packageArr[j] = package.ToString(); package.Clear(); } return packageArr; } View Code

  在main函數中測試一下生成的包

static void Main(string[] args) { string[] str = PackageBuilder.BuildPackage(20); for (int i = 0; i < 20; i++) { // str = PackageBuilder.BuildPackage(); Console.WriteLine(str[i]); // Thread.Sleep(500); } Console.Read(); } View Code

解決粘包問題有多種方法,根據發送包的結構,我采取的是根據包數據長度分包的方法。

如上圖所示,我們發送包結構為:包頭+數據長度+數據,包頭(HEAD|H1|)是固定長度,內容基本不變,數據長度(兩個字節)是變化的,數據(data:+隨機字符)也是變化的,其中數字之後的所有內容都是數據,包括'data:'。

前奏講完了下篇文章回到socket。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved