• 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。

  • 相关阅读:
    《信息学奥赛一本通》提高版题解索引
    QUERY [ 单调栈 ]
    [ 模拟退火 ] bzoj3860 平衡点
    [ 考试 ] 7.12
    离线和简单分治
    [ 校内OJ ] NOIP2019模拟赛(九)
    校内模拟考 (一)
    Codeforces 808E
    学习笔记—点分治
    [ 线段树+哈希 ] 反等差数列
  • 原文地址:https://www.cnblogs.com/gongheng/p/5698762.html
Copyright © 2020-2023  润新知