zoukankan      html  css  js  c++  java
  • 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。

  • 相关阅读:
    Codeforces 1316B String Modification
    Codeforces 1305C Kuroni and Impossible Calculation
    Codeforces 1305B Kuroni and Simple Strings
    Codeforces 1321D Navigation System
    Codeforces 1321C Remove Adjacent
    Codeforces 1321B Journey Planning
    Operating systems Chapter 6
    Operating systems Chapter 5
    Abandoned country HDU
    Computer HDU
  • 原文地址:https://www.cnblogs.com/gongheng/p/5698762.html
Copyright © 2011-2022 走看看