关于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();
        }
    }
}

 

posted @ 2015-03-23 15:21  小吴老师  阅读(2187)  评论(0编辑  收藏  举报