C#UDP通讯组件,支持拆包组包,丢包重发

自己仿照某商业组件开发的通讯模块,简单的调用便可实现传文件,即时通讯等内容.

如图,只需要绑定ip便可以通讯




组件下载地址:点击打开链接


调用的方法:

class Program
    {
        public static DataDispatcher dd;
        static void Main(string[] args)
        {
            dd = new DataDispatcher("192.168.167.105:8003");// 这里填写自己的ip
            dd.OnDataArrived += dd_OnDataArrived;
        }

        static void dd_OnDataArrived(byte[] in_listVariablePool)
        {
            Console.WriteLine("收到数据!");
            VariablePool vp = new VariablePool();
            vp.Init(in_listVariablePool);
            string ip = (string)vp.Get("IP",0);// 获取发送方的IP
            // 以上是接受数据
            // 下方是发送数据
            vp.Init();
            vp.Put("IP", ip);
            vp.Put("string", DateTime.Now.ToString());
            dd.Send(vp.GetVariablePool(),ip);
        }
    }

完整源代码:

0.目录:


1.主要通讯层DataDispatcher:

  using System;
  using System.Collections.Generic;
  using System.IO;
  using System.Linq;
  using System.Net;
  using System.Net.Sockets;
  using System.Runtime.Serialization.Formatters.Binary;
  using System.Threading;
  using SocketByUDPClassLibrary;
  
  namespace UDPClassLibrary
  {
      // 定义一个接受到数据时响应的委托
      public delegate void OnDataArrivedDelegate(byte[] in_listVariablePool);
  
      public class DataDispatcher
      {
          // 定义完成事件
          public event OnDataArrivedDelegate OnDataArrived;
  
          // 接收池                                            
          private Dictionary<int, DataPools> m_listInDataPools;
                                                               
          // 发送池                                            
          private Dictionary<int, DataPools> m_listOutDataPools;
  
          // 本机IP地址
          private IPEndPoint m_ipSelfIP;
  
          // 接收时的服务变量
          private Socket m_SocketService;
  
          private Thread m_threadStartService;
  
          // 线程锁
          private Mutex m_mutexPick;
  
          // 并发缓解
          private int m_iPush = 1;
  
          // 等待时间(毫秒)
          private int m_iWait = 500;
  
          /// <summary>
          /// 构造方法
          /// </summary>
          public DataDispatcher(string in_strIPInfo) 
          {
              // 获得IP
              m_ipSelfIP = StrToEndPoint(in_strIPInfo);
  
              // 数据池初始化
              m_listInDataPools = new Dictionary<int, DataPools>();
              m_listOutDataPools = new Dictionary<int, DataPools>();
  
              // 启动服务
              m_threadStartService = new Thread(StartService);
              m_threadStartService.Start();
  
              m_mutexPick = new Mutex();
  
              Thread threadTimer=new Thread(MyTime);
              threadTimer.Start();
              
          }
  
          /// <summary>
          /// 启动服务
          /// </summary>
          public void StartService()
          {
              // 使用Socket服务
              m_SocketService = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
  
              // 绑定网络地址
              m_SocketService.Bind(m_ipSelfIP);
  
              // 客户机IP
              IPEndPoint senderPoint = new IPEndPoint(IPAddress.Any, 0);
              EndPoint senderEndPoint = (EndPoint)(senderPoint);
              
              // 数据大小
              int iDataSize;
  
              // 字节数据
              byte[] bData = new byte[2048];
              List<byte[]> listIncomeDatas = new List<byte[]>();
              Thread threadAllotPack;
  
              object objCustomParm;
              // 循环监听是否取到包
              while (true)
              {
                  bData = new byte[2048];
  
                  //接收信息
                  iDataSize = m_SocketService.ReceiveFrom(bData, ref senderEndPoint);
  
                  // 如果是数据包 接收,如果是重发请求包 重发
                  if (iDataSize == 2048)
                  {
                      // 自定义参数
                      objCustomParm = new CustomParm(bData, senderEndPoint);
  
                      // 添加线程
                      threadAllotPack = new Thread(AllotPack);
  
                      // 分配收到的包
                      threadAllotPack.Start(objCustomParm);
  
                  }
                  else
                  {
                      // 根据信息重发
                      SendByInfo((ResendInfo)SetByteToValue(bData));
  
                      Console.WriteLine("收到请求包");
                  }
  
              }
          }
  
          /// <summary>
          /// 发送数据
          /// </summary>
          /// <param name="in_listToSendData"></param>
          /// <param name="in_strDesIP"></param>
          public void Send(byte[] in_listToSendData, string in_strDesIP)
          {
  
              List<byte> listByte = new List<byte>();
              listByte.AddRange(in_listToSendData);
              // 设置目标IP,设置TCP端口号
              IPEndPoint ipEndPoint = StrToEndPoint(in_strDesIP);
              
              // 调用包组件
              ByePacketUtil stPacketUtil = new ByePacketUtil();
  
              // 声明包组变量
              List<byte[]> listToSendDatas = stPacketUtil.SplitPacket(listByte);
  
              // 添加到发送池
              m_listOutDataPools.Add(stPacketUtil.GetJointHeadID(listToSendDatas[0]), new DataPools(0, 0, null, 30000, listToSendDatas));
  
              foreach (var blistPackage in listToSendDatas)
              {
                  //循环发送每个包
                  byte[] bSends = new byte[2048];
                  bSends = blistPackage.ToArray();
  
                  // 发送
                  m_SocketService.SendTo(bSends, bSends.Length, SocketFlags.None, ipEndPoint);
  
                  // 缓解并发压力
                  Thread.Sleep(m_iPush);
  
              }
  
              
  
          }
  
  
          private void SendByInfo(ResendInfo in_resendInfo)
          {
              int iKey = in_resendInfo.Key;
              int iIndex = in_resendInfo.Index;
  
              // 调用包组件
              ByePacketUtil packetUtil = new ByePacketUtil();
              
              if (m_listOutDataPools.ContainsKey(iKey))
              {
                  foreach (var bItem in m_listOutDataPools[iKey].PacketParking)
                  {
                      // 得到包的Index
                      int iPacketIndex = packetUtil.GetJointHeadIndex(bItem);
                      if (iPacketIndex==iIndex)
                      {
                          // 发送
                          m_SocketService.SendTo(bItem, bItem.Length, SocketFlags.None, in_resendInfo.MyEndPoint);
                      }
                  }
              }
              
          }
  
  
  
          /// <summary>
          /// 分配收到的包
          /// </summary>
          /// <param name="in_iData"></param>
          private void AllotPack(object in_objCustomParm)
          {
  
              byte[] listDataIn = ((CustomParm)in_objCustomParm).ParmBytes;
              EndPoint endPointIn = ((CustomParm)in_objCustomParm).ParmEndPoint;
  
              // 默认等待时间(毫秒)
              int iLeftDef = 30000;
  
              // 调用包组件
              ByePacketUtil packetUtil = new ByePacketUtil();
  
              // 得到包的ID
              int iPacketID = packetUtil.GetJointHeadID(listDataIn);
  
              // 得到包的Index
              int iPacketIndex = packetUtil.GetJointHeadIndex(listDataIn);
  
              // 得到包的份数
              int iPacketCount = packetUtil.GetJointHeadCount(listDataIn);
              
              m_mutexPick.WaitOne();
              Console.WriteLine("收到" + iPacketIndex + "/" + iPacketCount);
              // 操作接收池 
              if (m_listInDataPools.ContainsKey(iPacketID))
              {
                  // 存在就存一条
  
                  m_listInDataPools[iPacketID].PacketParking.Add(listDataIn);
                  m_listInDataPools[iPacketID].ExistPack++;
                  m_listInDataPools[iPacketID].LeftTime = iLeftDef;
  
               }
              else
              {
                  // 不存在就新建一条
                  List<byte[]> listTempDatas = new List<byte[]>();
                  listTempDatas.Add(listDataIn);
                  m_listInDataPools.Add(iPacketID, new DataPools(1, iPacketCount, endPointIn, iLeftDef, listTempDatas)); 
              }
  
              // 检查接收此包后是否有完整大包
              if (m_listInDataPools[iPacketID].PacketParking.Count() == iPacketCount)
              {
                  // 临时变量池
                  List<byte> listTempPool;
  
                  // 若大包完整执行封包
                  listTempPool = packetUtil.JointPacket(m_listInDataPools[iPacketID].PacketParking);
  
                  if (OnDataArrived != null)
                  {
                      // 事件抛出数据
                      OnDataArrived(listTempPool.ToArray());
                  }
  
  
                  Console.WriteLine("开始组包");
  
                  // 删除相关数据
                  RemoveByKey(iPacketID);
              }
              
              m_mutexPick.ReleaseMutex();
  
  
          }
  
          /// <summary>
          /// 每1秒执行一次丢包检查
          /// </summary>
          private void MyTime()
          {
              do
              {
                  Thread.Sleep(m_iWait);
                  CheckTimesIn();
  
              } while (true);
          }
  
          /// <summary>
          ///  检查接收池包否完整,若超时则释放资源
          /// </summary>
          private void CheckTimesIn()
          {
              foreach (int iItemKey in m_listInDataPools.Keys)
              {
                  DataPools stValue = m_listInDataPools[iItemKey];
                  stValue.LeftTime -= m_iWait;
  
                  if (stValue.LeftTime <= 0)
                  {
                      RemoveByKey(iItemKey);
                  }
                  else if (stValue.LeftTime <= 27000)
                  {
                      if (stValue.ExistPack < stValue.TotalPack)
                      {
                          List<ResendInfo> listResendInfos = FindLostPack(iItemKey, m_listInDataPools[iItemKey].EndPoint);
                          
                          // 请求重发
                          Resend(listResendInfos);
                      }
                  }
              }
          }
  
          /// <summary>
          ///  检查发送池包是否超时,若超时则释放资源
          /// </summary>
          private void CheckTimesOut()
          {
              foreach (int iItemKey in m_listOutDataPools.Keys)
              {
                  DataPools stValue = m_listOutDataPools[iItemKey];
                  stValue.LeftTime -= m_iWait;
  
                  if (stValue.LeftTime <= 0)
                  {
                      m_listOutDataPools.Remove(iItemKey);
                  }
                  
              }
          }
  
          private void Resend(List<ResendInfo> in_listResendInfos)
          {
              foreach (var stResendInfo in in_listResendInfos)
              {
                  // 缓解并发压力
                  Thread.Sleep(m_iPush);
  
                  byte[] bSends = SetValueToByte(stResendInfo);
  
                  // 发送
                  m_SocketService.SendTo(bSends, bSends.Length, SocketFlags.None, stResendInfo.EndPoint);
  
                  Console.WriteLine("重发:" + stResendInfo.Index+"---"+stResendInfo.Key);
              }
          }
  
          /// <summary>
          /// 转换出值字节(序列化)
          /// </summary>
          /// <param name="in_strFieldName">值名字</param>
          /// <returns></returns>
          public byte[] SetValueToByte(Object in_objValue)
          {
              var memoryStream = new MemoryStream();
              var formatter = new BinaryFormatter();
              formatter.Serialize(memoryStream, in_objValue);
              byte[] buffer = memoryStream.ToArray();
              memoryStream.Close();
              return buffer;
  
          }
  
          /// <summary>
          /// 反序列化
          /// </summary>
          /// <param name="in_strFieldName">值名字</param>
          /// <returns></returns>
          public Object SetByteToValue(byte[] in_listValue)
          {
              var memoryStream = new MemoryStream(in_listValue);
              var formatter = new BinaryFormatter();
              Object obj = formatter.Deserialize(memoryStream);
              memoryStream.Close();
              return obj;
  
          }
  
          /// <summary>
          ///  生成重发请求列表
          /// </summary>
          /// <param name="in_iPackKey"></param>
          /// <returns></returns>
          private List<ResendInfo> FindLostPack(int in_iPackKey,EndPoint in_EndPoint)
          {
              // 返回变量
              List<ResendInfo> listRes = new List<ResendInfo>();
  
              // 得到总包数
              int iCount = ((DataPools)m_listInDataPools[in_iPackKey]).TotalPack;
  
              // 总包数布尔值
              bool[] listAllTable = new bool[iCount];
              List<byte[]> listPools = m_listInDataPools[in_iPackKey].PacketParking;
  
              // 调用包组件
              ByePacketUtil packetUtil = new ByePacketUtil();
              foreach (byte[] listItem in listPools)
              {
                  int i = packetUtil.GetJointHeadIndex(listItem);
                  listAllTable[i] = true;
              }
  
  
              for (int i = 0; i < iCount; i++)
              {
                  if (listAllTable[i] == false)
                  {
                      listRes.Add(new ResendInfo(in_iPackKey, in_EndPoint, i, m_ipSelfIP));
                  }
              }
  
              return listRes;
          }
  
          /// <summary>
          /// 依据ID删除检查池的条目
          /// </summary>
          /// <param name="in_itemKey"></param>
          private void RemoveByKey(int in_itemKey)
          {
              m_listInDataPools.Remove(in_itemKey);
          }
  
          /// <summary>
          /// 字符串转ip+端口
          /// </summary>
          /// <returns></returns>
          private IPEndPoint StrToEndPoint(string in_strIPandPort)
          {
              string strIP = in_strIPandPort.Split(':')[0];
              string strPort = in_strIPandPort.Split(':')[1];
              IPAddress stIP = IPAddress.Parse(strIP);
              IPEndPoint resEndPoint = new IPEndPoint(stIP, int.Parse(strPort));
  
              return resEndPoint;
  
          }
      }
  }

2变量池(存放接收的原始对象):VariablePool

  using System;
  using System.Collections.Generic;
  using System.IO;
  using System.Linq;
  using System.Runtime.Serialization.Formatters.Binary;
  using System.Text;
  
  namespace SocketByUDPClassLibrary
  {
      public class VariablePool
      {
          private List<byte> m_listTransports;
          private int m_iPost;
          private static int PostInitValue = 2;
  
          /// <summary>
          /// 返回变量池
          /// </summary>
          /// <returns></returns>
          public byte[] GetVariablePool()
          {
              SetCount();
              return this.m_listTransports.ToArray();
          }
  
          /// <summary>
          /// Put时初始化
          /// </summary>
          public void Init()
          {
              m_listTransports = new List<byte>();
              m_listTransports.AddRange(BitConverter.GetBytes(new ushort()));
          }
  
          /// <summary>
          /// Get时初始化
          /// </summary>
          /// <param name="in_listData">接收到的List</param>
          public void Init(byte[] in_listData)
          {
              m_listTransports = new List<byte>();
              m_listTransports.AddRange(in_listData);
          }
  
          /// <summary>
          /// 取得下一个值
          /// </summary>
          /// <param name="in_iPost"></param>
          /// <returns></returns>
          public byte[] GetNextData()
          {
              byte bLength = m_listTransports[m_iPost];
              byte[] listResData = new byte[bLength];
              int iNextOne = 1;
  
              Array.Copy(m_listTransports.ToArray(), m_iPost + iNextOne, listResData, 0, bLength);
              m_iPost += bLength + iNextOne;
  
              return listResData;
          }
  
          /// <summary>
          /// 获得最大重复值数量
          /// </summary>
          /// <returns></returns>
          public int GetCount()
          {
              byte[] bUshot = new byte[2];
              bUshot[0] = m_listTransports[0];
              bUshot[1] = m_listTransports[1];
  
              return BitConverter.ToInt16(bUshot, 0);
          }
  
          /// <summary>
          /// 修改最大值
          /// </summary>
          public void SetCount()
          {
              Dictionary<string, int> listCountMap = new Dictionary<string, int>();
  
              string strName;
  
              m_iPost = PostInitValue;
              do
              {
                  strName = Encoding.Default.GetString(GetNextData());
                  if (listCountMap.ContainsKey(strName))
                  {
                      // 如果包含就增加1
                      listCountMap[strName]++;
                  }
                  else
                  {
                      // 不包含就新键一条
                      listCountMap.Add(strName, 1);
                  }
  
                  // 取值过程,只需要下标变动,不需要接收返回值
                  GetNextData();
  
                  // 当下标越界时结束循环
              } while (m_iPost < m_listTransports.Count);
  
              // 找出最大值并修改
              ushort usMax = (ushort)listCountMap.Values.Max();
              byte[] bUshot = BitConverter.GetBytes(usMax);
              m_listTransports[0] = bUshot[0];
              m_listTransports[1] = bUshot[1];
  
          }
  
          /// <summary>
          /// 从变量池取得对象
          /// </summary>
          /// <param name="in_strFieldName">字段名</param>
          /// <param name="in_iIndex">下标</param>
          /// <returns></returns>
          public object Get(string in_strFieldName, int in_iIndex)
          {
              int iCount = -1;
  
              List<byte> listResData = new List<byte>();
              string strName;
              byte[] listValue;
  
              m_iPost = PostInitValue;
              do
              {
                  strName = Encoding.Default.GetString(GetNextData());
                  if (strName == in_strFieldName)
                  {
                      // 匹配字段名
                      iCount++;
                  }
                  listValue = GetNextData();
                  if (iCount == in_iIndex)
                  {
                      // 匹配下标
                      return SetByteToValue(listValue);
                  }
                  // 当下标越界时结束循环
              } while (m_iPost < m_listTransports.Count);
  
              return null;
          }
  
          /// <summary>
          /// 转换出字段名字节
          /// </summary>
          /// <param name="in_strFieldName">字段名字</param>
          /// <returns></returns>
          public byte[] SetNameToByte(string in_strFieldName)
          {
              return System.Text.Encoding.ASCII.GetBytes(in_strFieldName);
          }
  
          /// <summary>
          /// 为变量池添加对象
          /// </summary>
          /// <param name="in_strFieldName"></param>
          /// <param name="in_objValue"></param>
          public void Put(string in_strFieldName, Object in_objValue)
          {
              // 分别转换出字段长度,字段,值长度,值
              byte[] listFieldName = SetNameToByte(in_strFieldName);
              byte bFieldNameLength = (byte)listFieldName.Length;
              byte[] listValue = SetValueToByte(in_objValue);
              byte bValueLength = (byte)listValue.Length;
  
  
  
              m_listTransports.Add(bFieldNameLength);
              m_listTransports.AddRange(listFieldName);
              m_listTransports.Add(bValueLength);
              m_listTransports.AddRange(listValue);
  
          }
  
          /// <summary>
          /// 转换出值字节(序列化)
          /// </summary>
          /// <param name="in_strFieldName">值名字</param>
          /// <returns></returns>
          public byte[] SetValueToByte(Object in_objValue)
          {
              var memoryStream = new MemoryStream();
              var formatter = new BinaryFormatter();
              formatter.Serialize(memoryStream, in_objValue);
              byte[] buffer = memoryStream.ToArray();
              memoryStream.Close();
              return buffer;
  
          }
  
          /// <summary>
          /// 反序列化
          /// </summary>
          /// <param name="in_strFieldName">值名字</param>
          /// <returns></returns>
          public Object SetByteToValue(byte[] in_listValue)
          {
              var memoryStream = new MemoryStream(in_listValue);
              var formatter = new BinaryFormatter();
              Object obj = formatter.Deserialize(memoryStream);
              memoryStream.Close();
              return obj;
  
          }
  
      }
  }

3.拆包解包工具类ByePacketUtil

using System;
using System.Collections.Generic;
using System.Linq;

namespace SocketByUDPClassLibrary
{
    public class ByePacketUtil
    {
        private int PacketMaxSize = 2048;
        private int UserMaxSize = 2040;
        private int HeadSize = 8;
        private int HeadIndexSize = 2;
        private int HeadCountSize = 2;
        private int HeadLengthSize = 2;
        private int HeadIDSize = 2;

        /// <summary>
        /// 拆包
        /// </summary>
        /// <param name="in_listPools"></param>
        /// <returns></returns>
        public List<byte[]> SplitPacket(List<byte> in_listPools)
        {
            List<byte[]> listResBytes = new List<byte[]>();

            // 得到总长度
            int iPoolLenght = in_listPools.Count();
            Int16 HeadIndex = -1;
            Int16 HeadCount = GetCount(iPoolLenght);
            Int16 HeadLength = 0;
            Int16 HeadID = CreateID();

            //剩下的长度
            int iLeftLenght = in_listPools.Count();
            bool bIsOver = false;
            do
            {
                // 序列自增
                HeadIndex++;

                // 判断剩下的长度是否还要再分一个包
                if (iLeftLenght > UserMaxSize)
                {
                    // 多个包就是HeadLength=UserMaxSize=2042
                    HeadLength = (Int16)(UserMaxSize);
                }
                else
                {
                    // 否则HeadLength等于剩下的大小
                    HeadLength = (Int16)iLeftLenght;

                    // 标记循环结束
                    bIsOver = true;
                }

                // 建立一个包
                List<byte> listResData = new List<byte>();

                // 添加包头
                listResData.AddRange(CreateHead(HeadIndex, HeadCount, HeadLength, HeadID));

                byte[] listPatyData = new byte[HeadLength];
                // 依照HeadLength长度剪切in_listPools
                Array.Copy(in_listPools.ToArray(), iPoolLenght - iLeftLenght, listPatyData, 0, (long)HeadLength);

                //添加剩下内容
                listResData.AddRange(listPatyData);
                while (listResData.Count<2048)
                {
                    listResData.AddRange(new byte[2048-listResData.Count]);
                }

                listResBytes.Add(listResData.ToArray());
                // 剩下的长度减掉单前包的长度
                iLeftLenght -= HeadLength;
            } while (!bIsOver);

            return listResBytes;
        }





        /// <summary>
        /// 封包
        /// </summary>
        /// <param name="in_listBytes"></param>
        /// <returns></returns>
        public List<byte> JointPacket(List<byte[]> in_listBytes)
        {
            List<byte> listResDatas = new List<byte>();
            Dictionary<short, List<byte>> listPacketMap = new Dictionary<short, List<byte>>();

            // 
            short iCount = GetJointHeadCount(in_listBytes[0]);
            foreach (byte[] listData in in_listBytes)
            {
                // 得到索引
                short iHeadIndex = GetJointHeadIndex(listData);

                // 得到长度
                short iHeadLength = GetJointHeadLength(listData);


                byte[] listToAdd = new byte[iHeadLength];
                Array.Copy(listData, HeadSize, listToAdd, 0, iHeadLength);

                // 添加一段到字典
                List<byte> listSignal = new List<byte>();
                listSignal.AddRange(listToAdd);
                listPacketMap.Add(iHeadIndex, listSignal);
            }

            // 循环按照顺序添加到列表
            for (short i = 0; i < iCount; i++)
            {
                listResDatas.AddRange(listPacketMap[i].ToArray());
            }
            return listResDatas;


        }


        /// <summary>
        /// 封包时得到包序号
        /// </summary>
        /// <param name="listData"></param>
        /// <returns></returns>
        public short GetJointHeadIndex(byte[] listData)
        {
            byte[] listIndex = new byte[HeadIndexSize];
            Array.Copy(listData, 0, listIndex, 0, HeadIndexSize);
            return BitConverter.ToInt16(listIndex, 0);
        }

        /// <summary>
        /// 封包时得到总包数
        /// </summary>
        /// <param name="listData"></param>
        /// <returns></returns>
        public short GetJointHeadCount(byte[] listData)
        {
            byte[] listCount = new byte[HeadCountSize];
            Array.Copy(listData, HeadIndexSize, listCount, 0, HeadCountSize);
            return BitConverter.ToInt16(listCount, 0);
        }

        /// <summary>
        /// 封包时得到内容长度
        /// </summary>
        /// <param name="listData"></param>
        /// <returns></returns>
        private short GetJointHeadLength(byte[] listData)
        {
            byte[] listLength = new byte[HeadLengthSize];
            Array.Copy(listData, HeadIndexSize + HeadCountSize, listLength, 0, HeadLengthSize);
            return BitConverter.ToInt16(listLength, 0);
        }

        /// <summary>
        /// 封包时得到包ID
        /// </summary>
        /// <param name="listData"></param>
        /// <returns></returns>
        public short GetJointHeadID(byte[] listData)
        {
            byte[] listID = new byte[HeadIndexSize];
            Array.Copy(listData, HeadIndexSize + HeadCountSize + HeadLengthSize, listID, 0, HeadIndexSize);
            return BitConverter.ToInt16(listID, 0);
        }



        /// <summary>
        /// 创建一个包头
        /// </summary>
        /// <param name="in_iHeadIndex">序号</param>
        /// <param name="in_iHeadCount">总数</param>
        /// <param name="in_iHeadLength">内容长度</param>
        /// <returns></returns>
        public byte[] CreateHead(Int16 in_iHeadIndex, Int16 in_iHeadCount, Int16 in_iHeadLength, Int16 in_iHeadID)
        {
            List<byte> bHead = new List<byte>();
            byte[] bHeadIndex = new byte[HeadIndexSize];
            byte[] bHeadCount = new byte[HeadCountSize];
            byte[] bHeadLength = new byte[HeadLengthSize];
            byte[] bHeadID = new byte[HeadIDSize];
            bHeadIndex = BitConverter.GetBytes(in_iHeadIndex);
            bHeadCount = BitConverter.GetBytes(in_iHeadCount);
            bHeadLength = BitConverter.GetBytes(in_iHeadLength);
            bHeadID = BitConverter.GetBytes(in_iHeadID);
            bHead.AddRange(bHeadIndex);
            bHead.AddRange(bHeadCount);
            bHead.AddRange(bHeadLength);
            bHead.AddRange(bHeadID);
            return bHead.ToArray();
        }

        /// <summary>
        /// 拆包时统计包的数量
        /// </summary>
        /// <param name="iPoolLenght"></param>
        /// <returns></returns>
        private short GetCount(int iPoolLenght)
        {
            return (short)(iPoolLenght / (PacketMaxSize - HeadSize) + 1);
        }

        /// <summary>
        /// 生成一个2字节的ID
        /// </summary>
        /// <returns></returns>
        private short CreateID()
        {
            return (short)(new Random().Next(65535));
        }
    }
}


4.一些自定义变量:CustomParm,DataPools,ResendInfo

  class CustomParm
      {
          public byte[] ParmBytes { get; set; }
          public EndPoint ParmEndPoint { get; set; }
  
          public CustomParm(byte[] ParmBytes, EndPoint ParmEndPoint) 
          {
              this.ParmBytes = ParmBytes;
              this.ParmEndPoint = ParmEndPoint;
          }
  
      }

  class DataPools
      {
          public int ExistPack { get; set; }
          public int TotalPack { get; set; }
          public EndPoint EndPoint { get; set; }
          public int LeftTime { get; set; }
          public List<byte[]> PacketParking { get; set; }
  
  
          public DataPools(int ExistPack, int TotalPack, EndPoint EndPoint, int LeftTime, List<byte[]> PacketParking)
          {
              this.ExistPack = ExistPack;
              this.TotalPack = TotalPack;
              this.EndPoint = EndPoint;
              this.LeftTime = LeftTime;
              this.PacketParking = PacketParking;
          }
      }


  [Serializable]// 注意这里的可序列化标志
      class ResendInfo
      {
          public int Key { get; set; }
          public EndPoint EndPoint { get; set; }
          public int Index { get; set; }
          public EndPoint MyEndPoint { get; set; }
  
          public ResendInfo(int Key, EndPoint EndPoint, int Index, EndPoint MyEndPoint) 
          {
              this.Key = Key;
              this.EndPoint = EndPoint;
              this.Index = Index;
              this.MyEndPoint = MyEndPoint;
          }
      }

    

发布了24 篇原创文章 · 获赞 5 · 访问量 3万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览