• 关于C#UDP接收缓冲区溢出处理方案


    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Net;
    using System.Net.Sockets;
    using System.Threading;
    
    namespace LAN
    {
        /// <summary>
        /// UdpSocket使用方法:
        /// 1:首先实例化UdpSocket(本机ip,本机端口) UdpSocket udpSocket = new UdpSocket(xx,xx);
        /// 2:然后执行初始化 udpSocket.Init(Rev3232)。Rev3232为需要用到的进程方法名
        /// 3:注意例程带//********//位置的操作。
        /// 4:关闭时先执行_threadFlag3232 = false;然后执行udpSocket.Close();
        /// 例程:
            //UdpSocket udpSocket = new UdpSocket(xx,xx); 
            //_threadFlag3232 = true;
            //udpSocket.Init(Rev3232);
            //
            // private void Rev3232()
            //{
            //    //接收数据处理线程 
            //    string msg = "";
            //    MyInvoke_3232 myI = new MyInvoke_3232(UpdateMsg_3232);
            //    while (_threadFlag3232)
            //    {
            //        if (udpSocket.RevQueue.Count == 0)//********//
            //        {
            //            Thread.Sleep(1);
            //            continue;
            //        }
            //        else
            //        {
                        
            //            byte[] data;
            //            lock (udpSocket.Lock)//********//
            //            {
            //                _test2 = udpSocket.RevQueue.Count;//********//
            //                data = udpSocket.RevQueue.Dequeue();//********//
            //            }
            //            int rlen = data.Length;
            //            int[] intDataBuff = new int[rlen / 4];
            //            for (int i = 0; i < rlen / 4; i++)
            //            {
            //                intDataBuff[i] = BitConverter.ToInt32(data, i * 4);
            //            }
    
            //            if ((intDataBuff[0] == 0x48449880) && ((intDataBuff[1] == 0x21111996) || (intDataBuff[1] == 0x21111997)))
            //            {
            //                _revFlag = 1;
            //            }
            //            BeginInvoke(myI, new object[] { data });
            //        }
            //    }
            //}
        /// </summary>
        public class  UdpSocket
        {
            #region 私有变量
            private EndPoint _sendIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
            private readonly byte[] _revDataBuffBytes = new byte[2048];
            private readonly AsyncCallback ReceiveCallback;
            private bool _closeFlag;
            #endregion
    
            #region 公有变量
            public Queue<byte[]> RevQueue = new Queue<byte[]>();
            public Socket MySocket;
            public readonly object Lock = new object();
            public string MyIpAddr ;
            public int MyPortNum;
            public Thread RevThread;
            public delegate void InvokeFun();
            
            #endregion
            /// <summary>
            /// 实例化UdpSocket
            /// </summary>
            /// <param name="myIpAddr">本机IP地址</param>
            /// <param name="myPortNum">本机需要打开的端口</param>
            public UdpSocket(string myIpAddr, int myPortNum)
            {
                ReceiveCallback = new AsyncCallback(OnDataReceived);
                MySocket = null;
                MyIpAddr = myIpAddr;
                MyPortNum = myPortNum;
    
            }
            /// <summary>
            /// 初始化
            /// </summary>
            /// <param name="revFun">线程功能函数(不带参数)</param>
            /// <returns>返回初始化成功的Socket</returns>
            public Socket Init(InvokeFun revFun)
            {
                try
                {
                    IPAddress lip;
                    IPAddress.TryParse(MyIpAddr, out lip);
                    //初始化socket,定义网络类型,数据连接类型与网络协议UDP
                    MySocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                    MySocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
                    IPEndPoint ipLocalPoint = new IPEndPoint(lip, MyPortNum);
                    //绑定网络地址
                    MySocket.Bind(ipLocalPoint);
                    MySocket.ReceiveBufferSize = 64 * 1024;
                    _closeFlag = true;
                    RevThread = new Thread(new ThreadStart(revFun));
                    RevThread.Start();
                    MySocket.BeginReceive(_revDataBuffBytes, 0, _revDataBuffBytes.Length, SocketFlags.None, ReceiveCallback, MySocket);
                    return MySocket;
                }
                catch
                {
                    return null;
                }
            }
            /// <summary>
            /// 初始化
            /// </summary>
            /// <returns>返回初始化成功的Socket</returns>
            public Socket Init()
            {
                try
                {
                    IPAddress lip;
                    IPAddress.TryParse(MyIpAddr, out lip);
                    //初始化socket,定义网络类型,数据连接类型与网络协议UDP
                    MySocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                    MySocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
                    IPEndPoint ipLocalPoint = new IPEndPoint(lip, MyPortNum);
                    //绑定网络地址
                    MySocket.Bind(ipLocalPoint);
                    MySocket.ReceiveBufferSize = 64 * 1024;
                    _closeFlag = true;
                    MySocket.BeginReceive(_revDataBuffBytes, 0, _revDataBuffBytes.Length, SocketFlags.None, ReceiveCallback, MySocket);
                    return MySocket;
                }
                catch
                {
                    return null;
                }
            }
            private void OnDataReceived(IAsyncResult ar)
            {
                try
                {
                    if (_closeFlag == true)
                    {
                        Socket udpSocket = ar.AsyncState as Socket;
                        int bytesRecved = udpSocket.EndReceive(ar);
                        byte[] data = new byte[bytesRecved];
                        Array.Copy(_revDataBuffBytes, data, bytesRecved);
                        lock (Lock)
                        {
                            RevQueue.Enqueue(data);
                        }
                        MySocket.BeginReceive(_revDataBuffBytes, 0, _revDataBuffBytes.Length, SocketFlags.None, ReceiveCallback, MySocket);
                    }
                    
                }
                catch 
                {
                   
                }
            }
    
            public void Close()
            {
                _closeFlag = false;
                if (RevThread != null)
                {
                    RevThread.Abort();
                }
                MySocket.Close();
                RevQueue.Clear();
            }
        }
    }
  • 相关阅读:
    kubernetes容器编排系统介绍
    whistle--全新的跨平台web调试工具
    深刻理解 React (一) ——JSX和虚拟DOM
    理想的互联网服务后台框架的九个要点
    gerrit的使用笔记
    Ubuntu 使用unzip解压乱码的问题
    ibus-libpinyin 无法选择除第一个外的候选词
    vscode Git:failed to execute git
    C Primer Plus 创建友好的输入界面 笔记
    Git学习笔记---安装与初始化 连接远程版本库
  • 原文地址:https://www.cnblogs.com/karl-wu/p/4359907.html
Copyright © 2020-2023  润新知