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);
  
  • 0
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的C#示例代码,实现UDP通讯帧数据的打包: ```csharp //定义UDP通讯帧结构体 struct UdpFrame { public byte FrameHead; public ushort DataLength; public byte[] Data; public byte FrameTail; //打包方法 public byte[] Pack() { byte[] result = new byte[4 + DataLength]; result[0] = FrameHead; result[1] = (byte)(DataLength & 0xFF); result[2] = (byte)((DataLength >> 8) & 0xFF); Array.Copy(Data, 0, result, 3, DataLength); result[3 + DataLength] = FrameTail; return result; } //解包方法 public static UdpFrame Unpack(byte[] data) { UdpFrame frame; frame.FrameHead = data[0]; frame.DataLength = (ushort)((data[2] << 8) | data[1]); frame.Data = new byte[frame.DataLength]; Array.Copy(data, 3, frame.Data, 0, frame.DataLength); frame.FrameTail = data[3 + frame.DataLength]; return frame; } } //示例代码 UdpFrame frame; frame.FrameHead = 0xAA; frame.DataLength = 5; frame.Data = new byte[5] { 0x01, 0x02, 0x03, 0x04, 0x05 }; frame.FrameTail = 0x55; byte[] packedData = frame.Pack(); //将packedData发送给UDP服务器 //接收到的数据 byte[] receivedData = new byte[1024]; //从UDP服务器接收到的数据存放在receivedData中 UdpFrame receivedFrame = UdpFrame.Unpack(receivedData); ``` 在示例代码中,定义了一个UdpFrame结构体,包括帧头、数据长度、数据、帧尾四个字段。其中,打包方法Pack将结构体打包成一个字节数组,解包方法Unpack从接收到的字节数组中解析出UdpFrame结构体。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值