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