using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Net.Sockets; using System.Threading; namespace Mozi.HttpEmbedded { //TODO 加入定时器并利用POLL判断远端是否断开 /// /// 异步单线程 /// public class SocketServer { //private static SocketServer _mSocketServer; private int _iPort = 9000; private int _maxListenCount = 10; private ConcurrentDictionary _socketDocker; private Socket _sc; /// /// 服务器启动事件 /// public event ServerStart OnServerStart; /// /// 客户端连接事件 /// public event ClientConnect OnClientConnect; /// /// 客户端断开连接时间 /// public event ClientDisConnect AfterClientDisConnect; /// /// 数据接收开始事件 /// public event ReceiveStart OnReceiveStart; /// /// 数据接收完成事件 /// public event ReceiveEnd AfterReceiveEnd; /// /// 服务器停用事件 /// public event AfterServerStop AfterServerStop; /// /// 端口 /// public int Port { get { return _iPort; } } public Socket SocketMain { get { return _sc; } } public SocketServer() { _socketDocker = new ConcurrentDictionary(); } //TODO 测试此处是否有BUG /// /// 启动服务器 /// /// public void StartServer(int port) { _iPort = port; if (_sc == null) { _sc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp); } else { _sc.Close(); } System.Net.IPEndPoint endpoint = new System.Net.IPEndPoint(System.Net.IPAddress.Any, _iPort); _sc.Bind(endpoint); _sc.Listen(_maxListenCount); //回调服务器启动事件 if (OnServerStart != null) { OnServerStart(this, new ServerArgs() { StartTime=DateTime.Now,StopTime=DateTime.MinValue }); } _sc.BeginAccept(new AsyncCallback(CallbackAccept), _sc); } /// /// 关闭服务器 /// public void StopServer() { _socketDocker.Clear(); try { _sc.Shutdown(SocketShutdown.Both); if (AfterServerStop != null) { AfterServerStop(_sc, null); } } catch { } } /// /// 开始连接回调 /// /// private void CallbackAccept(IAsyncResult iar) { Socket server = (Socket)iar.AsyncState; Socket client = server.EndAccept(iar); //接受新连接传入 server.BeginAccept(CallbackAccept, server); if (OnClientConnect != null) { OnClientConnect.BeginInvoke(this, new ClientConnectArgs() { Client=client },null,null); } StateObject so = new StateObject() { WorkSocket = client, Id = Guid.NewGuid().ToString(), IP = ((System.Net.IPEndPoint)client.RemoteEndPoint).Address.ToString(), RemotePort = ((System.Net.IPEndPoint)client.RemoteEndPoint).Port, }; _socketDocker.TryAdd(so.Id, client); try { client.BeginReceive(so.Buffer, 0, StateObject.BufferSize, 0, CallbackReceive, so); if (OnReceiveStart != null) { OnReceiveStart.BeginInvoke(this, new DataTransferArgs(), null, null); } } catch(Exception ex) { var ex2 = ex; } } /// /// 接收数据回调 /// /// private void CallbackReceive(IAsyncResult iar) { StateObject so = (StateObject)iar.AsyncState; Socket client = so.WorkSocket; if (client.Connected) { int iByteRead = client.EndReceive(iar); if (iByteRead >0) { //置空数据连接 so.ResetBuffer(iByteRead); if (client.Available > 0){ //Thread.Sleep(10); client.BeginReceive(so.Buffer, 0, StateObject.BufferSize, 0, CallbackReceive, so); }else{ InvokeAfterReceiveEnd(so, client); } } else { InvokeAfterReceiveEnd(so, client); } } else { InvokeAfterReceiveEnd(so, client); } } private void InvokeAfterReceiveEnd(StateObject so,Socket client) { RemoveClientSocket(so); if (AfterReceiveEnd != null) { AfterReceiveEnd(this, new DataTransferArgs() { Data = so.Data.ToArray(), IP = so.IP, Port = so.RemotePort, Socket = so.WorkSocket }); } } //TODO 此处开启Socket状态监听,对断开的链接进行关闭销毁 private void RemoveClientSocket(StateObject so) { Socket client; _socketDocker.TryRemove(so.Id, out client); } } }