using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; namespace HDL_ON.DAL.DriverLayer { //class AsyncUdpServer /// /// UdpClient 实现异步UDP服务器 /// public class AsyncUdpServer { #region Fields /// /// 服务器程序允许的最大客户端连接数 /// private int _maxClient; /// /// 当前的连接的客户端数 /// //private int _clientCount; /// /// 服务器使用的异步UdpClient /// private UdpClient _server; /// /// 客户端会话列表 /// //private List _clients; private bool disposed = false; /// /// 数据接受缓冲区 /// private byte[] _recvBuffer; #endregion #region Properties /// /// 服务器是否正在运行 /// public bool IsRunning { get; private set; } /// /// 监听的IP地址 /// public IPAddress Address { get; private set; } /// /// 监听的端口 /// public int Port { get; private set; } /// /// 通信使用的编码 /// public Encoding Encoding { get; set; } #endregion #region 构造函数 /// /// 异步UdpClient UDP服务器 /// /// 监听的端口 public AsyncUdpServer(int listenPort) : this(IPAddress.Any, listenPort, 10240) { } /// /// 异步UdpClient UDP服务器 /// /// 监听的终结点 public AsyncUdpServer(IPEndPoint localEP) : this(localEP.Address, localEP.Port, 10240) { } /// /// 异步UdpClient UDP服务器 /// /// 监听的IP地址 /// 监听的端口 /// 最大客户端数量 public AsyncUdpServer(IPAddress localIPAddress, int listenPort, int maxClient) { this.Address = localIPAddress; this.Port = listenPort; this.Encoding = Encoding.Default; _maxClient = maxClient; //_clients = new List(); _server = new UdpClient(new IPEndPoint(this.Address, this.Port)); uint IOC_IN = 0x80000000; uint IOC_VENDOR = 0x18000000; uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12; _server.Client.IOControl((int)SIO_UDP_CONNRESET, new byte[] { Convert.ToByte(false) }, null); _recvBuffer = new byte[_server.Client.ReceiveBufferSize]; } #endregion #region Method /// /// 启动服务器 /// /// 异步TCP服务器 public void Start() { try { if (!IsRunning) { IsRunning = true; _server.EnableBroadcast = true; _server.BeginReceive(ReceiveDataAsync, null); } } catch (Exception e) { } } /// /// 停止服务器 /// public void Stop() { try { //if (IsRunning) { IsRunning = false; _server.Close(); //TODO 关闭对所有客户端的连接 } } catch (Exception e) { } } /// /// 接收数据的方法 /// /// private void ReceiveDataAsync(IAsyncResult ar) { bool isReceive = false; try { var udpState = new AsyncUDPState(); IPEndPoint remote = null; udpState.buffer = _server.EndReceive(ar, ref remote); ; udpState.remote = remote; udpState.udpClient = _server; isReceive = true; receive(); //触发数据收到事件 RaiseDataReceived(udpState); } catch (Exception) { //TODO 处理异常 RaiseOtherException(null); } finally { if (!isReceive) { receive(); } } } void receive() { if (IsRunning && _server != null) { int count = 10; while (0 < count--) { try { _server.BeginReceive(ReceiveDataAsync, null); break; } catch (Exception e) { System.Threading.Thread.Sleep(100); } } } } /// /// 发送数据 /// /// /// public void Send(byte[] data, IPEndPoint remote) { try { RaisePrepareSend(null); _server.BeginSend(data, data.Length, remote, new AsyncCallback(SendCallback), null); } catch (Exception) { //TODO 异常处理 RaiseOtherException(null); } } private void SendCallback(IAsyncResult ar) { //if (ar.IsCompleted) { try { _server.EndSend(ar); //消息发送完毕事件 RaiseCompletedSend(null); } catch (Exception) { //TODO 数据发送失败事件 RaiseOtherException(null); } } } #endregion #region 事件 /// /// 接收到数据事件 /// public event EventHandler DataReceived; private void RaiseDataReceived(AsyncUDPState state) { if (DataReceived != null) { DataReceived(this, new AsyncUDPEventArgs(state)); } } /// /// 发送数据前的事件 /// public event EventHandler PrepareSend; /// /// 触发发送数据前的事件 /// /// private void RaisePrepareSend(AsyncUDPState state) { if (PrepareSend != null) { PrepareSend(this, new AsyncUDPEventArgs(state)); } } /// /// 数据发送完毕事件 /// public event EventHandler CompletedSend; /// /// 触发数据发送完毕的事件 /// /// private void RaiseCompletedSend(AsyncUDPState state) { if (CompletedSend != null) { CompletedSend(this, new AsyncUDPEventArgs(state)); } } /// /// 网络错误事件 /// public event EventHandler NetError; /// /// 触发网络错误事件 /// /// private void RaiseNetError(AsyncUDPState state) { if (NetError != null) { NetError(this, new AsyncUDPEventArgs(state)); } } /// /// 异常事件 /// public event EventHandler OtherException; /// /// 触发异常事件 /// /// private void RaiseOtherException(AsyncUDPState state, string descrip) { if (OtherException != null) { OtherException(this, new AsyncUDPEventArgs(descrip, state)); } } private void RaiseOtherException(AsyncUDPState state) { RaiseOtherException(state, ""); } #endregion #region Close /// /// 关闭一个与客户端之间的会话 /// /// 需要关闭的客户端会话对象 public void Close(AsyncUDPState state) { if (state != null) { //_clients.Remove(state); //_clientCount--; //TODO 触发关闭事件 } } /// /// 关闭所有的客户端会话,与所有的客户端连接会断开 /// public void CloseAllClient() { //foreach (AsyncUDPSocketState client in _clients) //{ // Close(client); //} //_clientCount = 0; //_clients.Clear(); } #endregion #region 释放 /// /// Performs application-defined tasks associated with freeing, /// releasing, or resetting unmanaged resources. /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } /// /// Releases unmanaged and - optionally - managed resources /// /// true to release /// both managed and unmanaged resources; false /// to release only unmanaged resources. protected virtual void Dispose(bool disposing) { if (!this.disposed) { if (disposing) { try { Stop(); if (_server != null) { _server = null; } } catch (SocketException) { //TODO RaiseOtherException(null); } } disposed = true; } } #endregion } } public class AsyncUDPState { // Client socket. public UdpClient udpClient = null; // Size of receive buffer. public const int BufferSize = 1024; // Receive buffer. public byte[] buffer = new byte[BufferSize]; // Received data string. public StringBuilder sb = new StringBuilder(); public IPEndPoint remote = new IPEndPoint(IPAddress.Any, 0); } /// /// UdpClient 异步UDP服务器事件参数类 /// public class AsyncUDPEventArgs : EventArgs { /// /// 提示信息 /// public string _msg; /// /// 客户端状态封装类 /// public AsyncUDPState _state; /// /// 是否已经处理过了 /// public bool IsHandled { get; set; } public AsyncUDPEventArgs(string msg) { this._msg = msg; IsHandled = false; } public AsyncUDPEventArgs(AsyncUDPState state) { this._state = state; IsHandled = false; } public AsyncUDPEventArgs(string msg, AsyncUDPState state) { this._msg = msg; this._state = state; IsHandled = false; } }