Socket解決粘包問題1


  粘包是指發送端發送的包速度過快,到接收端那邊多包並成一個包的現象,比如發送端連續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。


免責聲明!

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



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