zoukankan      html  css  js  c++  java
  • c#Udp分包组包方法

      udp通信协议,相信大家都知道这个。由于是无连接的协议,所有udp的传输效率比tcp高。但是udp协议传输较大的数据文件得分包

    最近写了个分包组包的方法,拿来和大家分享,如果有什么不妥的地方,欢迎点评

      

    分包的方法

    复制代码
     1   //每个包中二进制数组的长度
     2         public static int Count = 60000;
     3 
     4         //分包的方法,传入一个byte数组和包的编号(编号是用来判断收到数据是否是同一个包的)
     5         public static List<UdpPackage> GetList(byte[] bytes, int num)
     6         {
     7             List<UdpPackage> packages = new List<UdpPackage>();//定义一个包集合
     8             int count = 0;//用来记录包在包集合中的位置
     9             int nums = bytes.Length / Count;//分包后包集合中包的数量
    10             if (bytes.Length % Count > 0) nums++;
    11 
    12             //循环遍历传入的byte数组,根据每个包中的二进制数组长度(Count)来分割
    13             for (int i = 0; i <= bytes.Length; i += Count)
    14             {
    15                 count++;//位置++
    16 
    17                 byte[] bs = new byte[Count];
    18                 int all = Count;
    19                 //判断最后一个分包是否超过剩余byte数组的长度
    20                 //如果超过,则最后一个包的长度为剩余byte数组的长度
    21                 if (i + Count > bytes.Length)
    22                     all = bytes.Length - i;
    23                 //将传入byte数组copy到包中
    24                 Buffer.BlockCopy(bytes, i, bs, 0, all);
    25                 packages.Add(new UdpPackage
    26                 {
    27                     Bytes = bs,
    28                     PacketNum = num,
    29                     PacketAtNum = count,
    30                     PacketCount = nums
    31                 });
    32             }
    33             return packages;
    34         }
    35         
    复制代码

    组包的方法

    复制代码
            //组合包方法,传入一个包集合,和包的编号
            public static byte[] GetBytes(UdpPackage package,int count)
            {
                byte[] bytes = null;//接包二进制集合
                udps.Add(package);//把传入的包add进包集合中
    
                //linq查询,查出包集合中所有和传入包编号拥有相同编号的包,并根据所在包
                //的位置排序
                var result = from n in udps where n.PacketNum == count 
                             orderby n.PacketAtNum 
                             select n;
    
                //判断查出包的集合是否跟分包时的数量一样
                if (result.Count() == package.PacketCount)
                {
                    bytes=new byte[5120000];//初始化接包二进制数组
                    int jiShu = 0;//定义一个计数器
    
                    //遍历所有查询结果中的包,把每个包中的二进制数组组合起来
                    foreach (UdpPackage v in result)
                    {
                        //把当前循环中包的二进制集合copy到接包数组中,从jishu*Count开始
                        v.Bytes.CopyTo(bytes, jiShu * Count);
                        //计数器++
                        jiShu++;
                    }
    
                    //调用清包方法,清除所有组包完成的包
                    clear(count);
                        
                }
    
                return bytes;
            }
    
            //清除方法,根据传入的包编号删除所有包集合中拥有此包编号的包
            private static void clear(int index)
            {
                for (int i = 0; i < udps.Count;)
                {
                    //判读包的编号是否已传入的编号相同
                    //如果相同则删除,否则进入下一个
                    if (udps[i].PacketNum == index)
                        udps.Remove(udps[i]);
                    else
                        i++;
                }
            }
    复制代码

    包类

       [Serializable]
        public class UdpPackage
        {
           
            public byte[] Bytes { get; set; }//包中的二进制数据
            public int PacketNum { get; set; }//所属包集合的编号
            public int PacketCount { get; set; }//所属包集合中包的个数
            public int PacketAtNum { get; set; }//所属包集合中的第几个包
    
        }

    这个用来测试过udp协议写的局域网屏幕监控,测试完全没问题

  • 相关阅读:
    如何在自定义端口上运行 Spring Boot 应用程序?
    FileUpload拦截器
    UI标签
    OGNL
    你对测试最大的兴趣在哪里?为什么?
    举例说明同步和异步。
    git 克隆分支
    JQuery 选择器
    JQuery对象和Dom对象
    简单的JQuery之Ready
  • 原文地址:https://www.cnblogs.com/caoxianbing/p/3462507.html
Copyright © 2011-2022 走看看