SocketTcpServer

自定义SocketTcpServer,虽然现在有很多这样的组件,但是有时候还是需要把它集成在你的框架或者产品中,不需要特别强大的功能,根据需求定制。最基本的一个问题是判断数据包的结束,没有像supersocket那样默认以换行作为一个命令的结束,如果需要可以改善。

  1     public interface ISocketTcpServer
  2     {
  3         void Listen();
  4         void Stop();
  5         void SendData(byte[] data, Socket client);
  6 
  7         event ReceiveDataHandler ReceivedDataEvent;
  8         event OnlineChangeHandler OnlineChangeEvent;
  9         event ErrorHandler ErrorEvent;
 10     }
 11 
 12     public delegate void ReceiveDataHandler(SocketState state);
 13 
 14     public delegate void OnlineChangeHandler(int onlines, EndPoint client);
 15 
 16     public delegate void ErrorHandler(string error, EndPoint client);
 17 
 18     public class SocketTcpServer : ISocketTcpServer
 19     {
 20         private readonly Socket _tcpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
 21         public readonly EndPoint LocalPoint;
 22         public readonly List<SocketState> ClientList = new List<SocketState>();
 23         public bool IsListening;
 24 
 25         public SocketTcpServer(IPEndPoint localPoint)
 26         {
 27             LocalPoint = localPoint;
 28         }
 29 
 30         public void Listen()
 31         {
 32             _tcpSocket.Bind(LocalPoint);
 33             _tcpSocket.Listen(1000);
 34             _tcpSocket.BeginAccept(AcceptClientCallBack, _tcpSocket);
 35             IsListening = true;
 36         }
 37 
 38         public void Stop()
 39         {
 40             IsListening = false;
 41             foreach (var state in ClientList)
 42             {
 43                 state.ClientSocket.Close();
 44             }
 45             ClientList.Clear();
 46             _tcpSocket.Close();
 47             OnlineChangeEvent?.Invoke(ClientList.Count, new IPEndPoint(IPAddress.Any, 0));
 48         }
 49 
 50         private void AcceptClientCallBack(IAsyncResult ar)
 51         {
 52             var server = ar.AsyncState as Socket;
 53             if (IsListening && server != null)
 54             {
 55                 try
 56                 {
 57                     var client = server.EndAccept(ar);
 58                     var clientState = new SocketState()
 59                     {
 60                         ClientSocket = client,
 61                         RemotePoint = client.RemoteEndPoint,
 62                     };
 63                     var tem = ClientList.FirstOrDefault(x => x.RemotePoint.Equals(clientState.RemotePoint));
 64                     if (tem != null)
 65                     {
 66                         tem.ClientSocket.Close();
 67                         ClientList.Remove(tem);
 68                     }
 69                     ClientList.Add(clientState);
 70                     BeginReveive(client);
 71                     OnlineChangeEvent?.Invoke(ClientList.Count, client.RemoteEndPoint);
 72                 }
 73                 catch (Exception error)
 74                 {
 75                     ErrorEvent?.Invoke(error.Message, null);
 76                 }
 77                 finally
 78                 {
 79                     server.BeginAccept(AcceptClientCallBack, server);
 80                 }
 81             }
 82         }
 83 
 84         private void BeginReveive(Socket client)
 85         {
 86             if (client.Connected)
 87             {
 88                 var state = new SocketState()
 89                 {
 90                     ClientSocket = client,
 91                     RemotePoint = client.RemoteEndPoint,
 92                 };
 93                 client.BeginReceiveFrom(
 94                     state.Buffer,
 95                     0,
 96                     state.Buffer.Length,
 97                     SocketFlags.None,
 98                     ref state.RemotePoint,
 99                     ReceiveCallback,
100                     state);
101             }
102         }
103 
104         private void ReceiveCallback(IAsyncResult ar)
105         {
106             var state = ar.AsyncState as SocketState;
107             try
108             {
109                 if (state != null && state.ClientSocket.Connected)
110                 {
111                     state.DataLen = state.ClientSocket.EndReceiveFrom(ar, ref state.RemotePoint);
112                     if (state.DataLen == 0)
113                     {
114                         state.ClientSocket.Close();
115                         var tem = ClientList.FirstOrDefault(x => x.RemotePoint.Equals(state.RemotePoint));
116                         ClientList.Remove(tem);
117                         OnlineChangeEvent?.Invoke(ClientList.Count, state.RemotePoint);
118                     }
119                     else
120                     {
121                         byte[] receivedData = new byte[state.DataLen];
122                         Array.Copy(state.Buffer, 0, receivedData, 0, state.DataLen);
123                         state.Buffer = receivedData;
124                         ReceivedDataEvent?.Invoke(state);
125                     }
126                 }
127             }
128             catch (Exception error)
129             {
130                 ErrorEvent?.Invoke(error.Message, state.RemotePoint);
131                 state.ClientSocket.Close();
132                 var tem = ClientList.FirstOrDefault(x => x.RemotePoint.Equals(state.RemotePoint));
133                 ClientList.Remove(tem);
134                 OnlineChangeEvent?.Invoke(ClientList.Count, state.RemotePoint);
135             }
136             finally
137             {
138                 if (state != null) BeginReveive(state.ClientSocket);
139             }
140         }
141 
142         public void SendData(byte[] data, Socket client)
143         {
144             if (client.Connected)
145             {
146                 var state = new SocketState()
147                 {
148                     ClientSocket = client,
149                     RemotePoint = client.RemoteEndPoint,
150                     Buffer = data,
151                     DataLen = data.Length,
152                 };
153                 client.BeginSendTo(data, 0, data.Length, SocketFlags.None, state.RemotePoint, SendCallback, state);
154             }
155         }
156 
157         private void SendCallback(IAsyncResult ar)
158         {
159             var state = ar.AsyncState as SocketState;
160             try
161             {
162                 if (state != null && state.ClientSocket.Connected)
163                 {
164                     state.ClientSocket.EndSendTo(ar);
165                 }
166             }
167             catch (Exception error)
168             {
169                 ErrorEvent?.Invoke(error.Message, state.RemotePoint);
170             }
171         }
172 
173         public event ReceiveDataHandler ReceivedDataEvent;
174 
175         public event OnlineChangeHandler OnlineChangeEvent;
176 
177         public event ErrorHandler ErrorEvent;
178     }
179 
180     public class SocketState
181     {
182         public byte[] Buffer = new byte[1024*24];
183         public Socket ClientSocket;
184         public int DataLen;
185         public EndPoint RemotePoint;
186     }

 

posted on 2016-07-31 20:12  jonney_wang  阅读(389)  评论(0编辑  收藏  举报

导航