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;
          }
      }

    

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章