首页 > 代码库 > c#中关于udp实现可靠地传输(数据包的分组发送) 升级版
c#中关于udp实现可靠地传输(数据包的分组发送) 升级版
在c#中关于udp实现可靠地传输(数据包的分组发送) 中我们讨论了,UDP包的发送,但是上一个程序有一个问题,就是数据比较大,一个Message类序列化后都有2048B,而实际的数据量也就不过 50B罢了,这就说明其中数据有效的很少,这样当传送的数据包过多后,效率会极大的降低。因此我们只有想办法减少冗余数据。
此项目中借用了飞鸽传书中的一个《FSLib.IPMessager》项目中的思想,并加以改善,感谢此项目作者,让我对此有了深刻的理解
我们需要自己定义数据的传输结构 我们可以定义一个数据头 其中包含一些基本的必要信息,然后再把要传送的数据写入尾部。我把这部分代码贴出来,要具体完整的项目请到我的资源区下载,由于LZ原创希望给点分哈!
项目下载地址
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; namespace Netframe.Model { /// <summary> /// 消息封包类 /// </summary> public class MessagePacker { /* * 消息包注意: * 1.第一位始终是2(ASCII码50) * 2.第二位到第九位是一个long类型的整数,代表消息编号 * 3.第十位到第十三位是一个int类型的整数,代表消息内容总长度 * 4.第十四位到第十七位是一个int类型的整数,代表分包的总数 * 5.第十八位到第二十一位是一个int类型的整数,代表当前的分包编号 * 6.第二十二位表示是否需要返回一个确认标识(1/0) * 7.第二十三到第三十一位是保留的(Reserved) * 8.第三十二字节以后是数据包 * */ /// <summary> /// 消息版本号 /// </summary> public static byte VersionHeader { get { return 50; } } /// <summary> /// 返回当前消息封包的头字节数 /// </summary> public static int PackageHeaderLength { get { return 32; } } /// <summary> /// 获得消息包的字节流 /// </summary> /// <param name="message">要打包的消息对象</param> /// <returns></returns> public static UdpPacketMsg[] BuildNetworkMessage(Msg message) { if (message.ExtendMessageBytes != null) { return BuildNetworkMessage( message.RemoteAddr, message.PackageNo, message.Command, message.UserName, message.HostName, message.Type, message.NormalMsgBytes, message.ExtendMessageBytes, message.IsRequireReceive ); } else { return BuildNetworkMessage( message.RemoteAddr, message.PackageNo, message.Command, message.UserName, message.HostName, message.Type, System.Text.Encoding.Unicode.GetBytes(message.NormalMsg), System.Text.Encoding.Unicode.GetBytes(message.ExtendMessage), message.IsRequireReceive ); } } /// <summary> /// 获得消息包的字节流 /// </summary> /// <param name="remoteIp">远程主机地址</param> /// <param name="packageNo">包编号</param> /// <param name="command">命令</param> /// <param name="options">参数</param> /// <param name="userName">用户名</param> /// <param name="hostName">主机名</param> /// <param name="content">正文消息</param> /// <param name="extendContents">扩展消息</param> /// <returns></returns> public static UdpPacketMsg[] BuildNetworkMessage(IPEndPoint remoteIp, long packageNo, Commands command, string userName, string hostName,Consts type ,byte[] content, byte[] extendContents, bool RequireReceiveCheck) { //每次发送所能容下的数据量 int maxBytesPerPackage = (int)Consts.MAX_UDP_PACKAGE_LENGTH - PackageHeaderLength; //压缩数据流 System.IO.MemoryStream ms = new System.IO.MemoryStream(); System.IO.Compression.GZipStream zip = new System.IO.Compression.GZipStream(ms, System.IO.Compression.CompressionMode.Compress); System.IO.BinaryWriter bw = new System.IO.BinaryWriter(zip, System.Text.Encoding.Unicode); //写入头部数据 bw.Write(packageNo); //包编号 bw.Write(userName); //用户名 bw.Write(hostName); //主机名 bw.Write((long)command); //命令 bw.Write((long)type); //数据类型 bw.Write(content == null ? 0 : content.Length);//数据长度 //写入消息数据 if (content != null) bw.Write(content); bw.Write(extendContents == null ? 0 : extendContents.Length);//补充数据长度 if (extendContents != null) bw.Write(extendContents); //bw.Close(); //zip.Close(); ms.Flush(); ms.Seek(0, System.IO.SeekOrigin.Begin); //打包数据总量 int dataLength = (int)ms.Length; int packageCount = (int)Math.Ceiling(dataLength * 1.0 / maxBytesPerPackage); UdpPacketMsg[] pnma = new UdpPacketMsg[packageCount]; for (int i = 0; i < packageCount; i++) { int count = i == packageCount - 1 ? dataLength - maxBytesPerPackage * (packageCount - 1) : maxBytesPerPackage; byte[] buf = new byte[count + PackageHeaderLength]; buf[0] = VersionHeader;//版本号 第1位 BitConverter.GetBytes(packageNo).CopyTo(buf, 1);//消息编号 第2到9位 long类型的整数 BitConverter.GetBytes(dataLength).CopyTo(buf, 9);//消息内容长度 第10到13位 int类型的整数 BitConverter.GetBytes(packageCount).CopyTo(buf, 13);//分包总数 第14位到第17位 int类型的整数 BitConverter.GetBytes(i).CopyTo(buf, 17);//分包编号 第18位到第21位 int类型的整数 buf[21] = RequireReceiveCheck ? (byte)1 : (byte)0;//是否回确认包 第22位 //第23到第31位是保留的(Reserved) ms.Read(buf, 32, buf.Length - 32);//第32字节以后是,具体的数据包 pnma[i] = new UdpPacketMsg() { Data = http://www.mamicode.com/buf,>
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。