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协议写的局域网屏幕监控,测试完全没问题

 

posted @ 2013-12-07 10:33  caoxianbing  阅读(1010)  评论(1编辑  收藏  举报