using System; using System.Collections.Generic; using System.Text; using System.Net.Sockets; using System.Net; namespace IStation { /// /// TcpListener实现异步TCP服务器 /// public class AsyncTcpServer: IDisposable { #region 私有字段 private readonly object _obj = new object();//lock对象 private TcpListener _listener;//服务器使用的异步TcpListener private List _tcpClientStates;//客户端会话列表 private bool _disposed = false;//是否已经释放 #endregion #region 属性 /// /// 服务器是否正在运行 /// public bool IsRunning { get; private set; } /// /// 监听的IP地址 /// public IPAddress Address { get; private set; } /// /// 监听的端口 /// public int Port { get; private set; } #endregion #region 构造函数 /// /// 异步TCP服务器 /// /// 监听的IP地址 /// 监听的端口 public AsyncTcpServer(IPAddress ipAddress, int port) { this.Address = ipAddress; this.Port = port; _tcpClientStates = new List(); _listener = new TcpListener(Address, Port); _listener.AllowNatTraversal(true); } #endregion #region Method /// /// 启动服务器 /// public void Start() { if (!this.IsRunning) { this.IsRunning = true; _listener.Start(); _listener.BeginAcceptTcpClient( new AsyncCallback(HandleTcpClientAccepted), _listener); } } /// /// 启动服务器 /// /// /// 服务器所允许的挂起连接序列的最大长度 /// public void Start(int backlog) { if (!this.IsRunning) { this.IsRunning = true; _listener.Start(backlog); _listener.BeginAcceptTcpClient( new AsyncCallback(HandleTcpClientAccepted), _listener); } } /// /// 停止服务器 /// public void Stop() { if (IsRunning) { IsRunning = false; _listener.Stop(); lock (_obj) { //关闭所有客户端连接 _tcpClientStates.ForEach(x=>x.Close()); _tcpClientStates.Clear(); } } } /// /// 处理客户端连接的函数 /// /// private void HandleTcpClientAccepted(IAsyncResult ar) { if (IsRunning) { //TcpListener tcpListener = (TcpListener)ar.AsyncState; var client = _listener.EndAcceptTcpClient(ar); var buffer = new byte[client.ReceiveBufferSize]; var state = new TcpClientState(client,buffer); lock (_obj) { _tcpClientStates.Add(state); RaiseClientConnected(state); } NetworkStream stream = state.NetworkStream; //开始异步读取数据 stream.BeginRead(state.Buffer, 0, state.Buffer.Length, HandleDataReceived, state); _listener.BeginAcceptTcpClient( new AsyncCallback(HandleTcpClientAccepted), ar.AsyncState); } } /// /// 数据接收回调函数 /// /// private void HandleDataReceived(IAsyncResult ar) { if (IsRunning) { var state = (TcpClientState)ar.AsyncState; var stream = state.NetworkStream; int recv = 0; try { recv = stream.EndRead(ar); } catch { recv = 0; } if (recv == 0) { // connection has been closed lock (_obj) { _tcpClientStates.Remove(state); //触发客户端连接断开事件 RaiseClientDisconnected(state); return; } } // received byte and trigger event notification byte[] buff = new byte[recv]; Buffer.BlockCopy(state.Buffer, 0, buff, 0, recv); //触发数据收到事件 RaiseDataReceived(state,buff); // continue listening for tcp datagram packets stream.BeginRead(state.Buffer, 0, state.Buffer.Length, HandleDataReceived, state); } } /// /// 发送数据 /// /// 接收数据的客户端会话 /// 数据报文 public void Send(TcpClientState state, byte[] data) { if (!IsRunning) return; state.NetworkStream.BeginWrite(data, 0, data.Length, SendDataEnd, state.TcpClient); } /// /// 发送数据完成处理函数 /// /// 目标客户端Socket private void SendDataEnd(IAsyncResult ar) { ((TcpClient)ar.AsyncState).GetStream().EndWrite(ar); } #endregion #region 事件 /// /// 与客户端的连接已建立事件 /// public event EventHandler TcpClientConnected; /// /// 与客户端的连接已断开事件 /// public event EventHandler TcpClientDisconnected; /// /// 接收到数据事件 /// public event Action DataReceived; /// /// 触发客户端连接事件 /// /// private void RaiseClientConnected(TcpClientState state) { if(this.TcpClientConnected!=null) this.TcpClientConnected(this, new AsyncTcpEventArgs(state)); } /// /// 触发客户端连接断开事件 /// /// private void RaiseClientDisconnected(TcpClientState state) { if(this.TcpClientDisconnected!=null) this.TcpClientDisconnected(this, new AsyncTcpEventArgs(state)); } /// /// 触发接收到数据报文事件 /// /// private void RaiseDataReceived(TcpClientState state,byte[] bytes) { if(this.DataReceived!=null) this.DataReceived(state,bytes); } #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 (_listener != null) { _listener = null; } } catch //(SocketException ex) { //TODO //throw ex; } } _disposed = true; } } #endregion } }