自定义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 }
时间: 2024-10-14 13:39:50