使用完成端口(IOCP)

 1 using System;
 2 using System.Net;
 3 using System.Net.Sockets;
 4 
 5 namespace JCommon.Net
 6 {
 7     /// <summary>
 8     /// 存储客户端信息, 这个可以根据自己的实际情况来定义
 9     /// </summary>
10     public class AsyncUserToken
11     {
12         public IPEndPoint EndPort;
13         
14         public Socket Socket;
15         
16         /// <summary>
17         /// 连接时间
18         /// </summary>
19         public DateTime ConnectTime { get; set; }
20     }
21 }
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Net.Sockets;
 4 
 5 namespace JCommon.Net
 6 {
 7     /// <summary>
 8     /// 该类创建一个大缓冲区,该缓冲区可以分配给 SocketAsyncEventArgs 对象;
 9     /// 这使bufffer易于重用,并能防止碎片化堆内存;
10     /// BufferManager 类的操作不是线程安全的。
11     /// </summary>
12     internal class BufferManager
13     {
14         private int m_numBytes;             // 字节总数
15         private byte[] m_buffer;            // 字节数组
16         private Stack<int> m_freeIndexPool;
17         private int m_currentIndex;
18         private int m_bufferSize;
19 
20         public BufferManager(int totalBytes, int bufferSize)
21         {
22             this.m_numBytes = totalBytes;
23             this.m_currentIndex = 0;
24             this.m_bufferSize = bufferSize;
25             this.m_freeIndexPool = new Stack<int>();
26         }
27 
28         public void InitBuffer()
29         {
30             this.m_buffer = new byte[this.m_numBytes];
31         }
32 
33         /// <summary>
34         /// 将缓冲区分配给 SocketAsyncEventArgs 对象
35         /// </summary>
36         /// <param name="args"></param>
37         /// <returns></returns>
38         public bool SetBuffer(SocketAsyncEventArgs args)
39         {
40             if (this.m_freeIndexPool.Count > 0)
41             {
42                 args.SetBuffer(this.m_buffer, this.m_freeIndexPool.Pop(), this.m_bufferSize);
43             }
44             else
45             {
46                 if (this.m_numBytes - this.m_bufferSize < this.m_currentIndex)
47                 {
48                     return false;
49                 }
50                 args.SetBuffer(this.m_buffer, this.m_currentIndex, this.m_bufferSize);
51                 this.m_currentIndex += this.m_bufferSize;
52             }
53             return true;
54         }
55 
56         /// <summary>
57         /// 从 SocketAsyncEventArgs 对象回收缓冲区
58         /// </summary>
59         /// <param name="args"></param>
60         public void FreeBuffer(SocketAsyncEventArgs args)
61         {
62             this.m_freeIndexPool.Push(args.Offset);
63             args.SetBuffer(null, 0, 0);
64         }
65     }
66 }
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Net.Sockets;
 4 
 5 namespace JCommon.Net
 6 {
 7     /// <summary>
 8     /// 表示可重用SocketAsyncEventArgs对象的集合
 9     /// </summary>
10     internal class SocketAsyncEventArgsPool
11     {
12         private Stack<SocketAsyncEventArgs> m_pool;
13         
14         public SocketAsyncEventArgsPool(int capacity)
15         {
16             this.m_pool = new Stack<SocketAsyncEventArgs>(capacity);
17         }
18 
19         public void Push(SocketAsyncEventArgs item)
20         {
21             if (item == null)
22             {
23                 throw new ArgumentNullException("Items added to a SocketAsyncEventArgsPool cannot be null");
24             }
25             lock (this.m_pool)
26             {
27                 this.m_pool.Push(item);
28             }
29         }
30 
31         public SocketAsyncEventArgs Pop()
32         {
33             SocketAsyncEventArgs result;
34             lock (this.m_pool)
35             {
36                 result = this.m_pool.Pop();
37             }
38             return result;
39         }
40 
41         public int Count
42         {
43             get
44             {
45                 return this.m_pool.Count;
46             }
47         }
48     }
49 }
  1 using System;
  2 using System.Net;
  3 using System.Net.Sockets;
  4 using System.Text;
  5 using System.Threading;
  6 
  7 namespace JCommon.Net
  8 {
  9     public class SocketClient
 10     {
 11         public event EventHandler<SocketAsyncEventArgs> OnReceived;
 12         public event EventHandler<SocketAsyncEventArgs> OnSendCompleted;
 13         public event EventHandler<SocketAsyncEventArgs> OnConnectCompleted;
 14         public event EventHandler<SocketAsyncEventArgs> OnConnectionClosed;
 15 
 16         private Socket sock;
 17         private byte[] sendBuffer;
 18         private int receiveBufferCapacity;
 19         private int writeBufferCapacity;
 20         private SocketAsyncEventArgs readArgs = new SocketAsyncEventArgs();
 21         private SocketAsyncEventArgs writeArgs = new SocketAsyncEventArgs();
 22         private SocketAsyncEventArgs connectArgs;
 23         private AutoResetEvent sendCompletedEvent = new AutoResetEvent(false);
 24         private object sync_disconn = new object();
 25         private byte[] receiveBuffer;
 26 
 27         public SocketClient(int receiveCapacity = 1024, int sendCapacity = 256)
 28         {
 29             this.receiveBufferCapacity = receiveCapacity;
 30             this.writeBufferCapacity = sendCapacity;
 31             this.sock = new Socket(SocketType.Stream, ProtocolType.Tcp);
 32             this.receiveBuffer = new byte[receiveCapacity];
 33             this.readArgs.SetBuffer(this.receiveBuffer, 0, receiveCapacity);
 34             this.readArgs.Completed += this.IO_Completed;
 35             this.readArgs.UserToken = new AsyncUserToken
 36             {
 37                 Socket = this.sock
 38             };
 39             this.sendBuffer = new byte[sendCapacity];
 40             this.writeArgs.SetBuffer(this.sendBuffer, 0, sendCapacity);
 41             this.writeArgs.Completed += this.IO_Completed;
 42             this.writeArgs.UserToken = new AsyncUserToken
 43             {
 44                 Socket = this.sock
 45             };
 46         }
 47 
 48         ~SocketClient()
 49         {
 50             this.Disconnect(false);
 51         }
 52 
 53         public bool Connect(bool block = true)
 54         {
 55             if (this.sock != null && this.sock.Connected)
 56             {
 57                 return true;
 58             }
 59             if (this.sock == null)
 60             {
 61                 this.sock = new Socket(SocketType.Stream, ProtocolType.Tcp);
 62                 this.readArgs = new SocketAsyncEventArgs();
 63                 this.readArgs.SetBuffer(this.receiveBuffer, 0, this.receiveBufferCapacity);
 64                 this.readArgs.Completed += this.IO_Completed;
 65                 this.readArgs.UserToken = new AsyncUserToken
 66                 {
 67                     Socket = this.sock
 68                 };
 69                 this.writeArgs = new SocketAsyncEventArgs();
 70                 this.writeArgs.SetBuffer(this.sendBuffer, 0, this.writeBufferCapacity);
 71                 this.writeArgs.Completed += this.IO_Completed;
 72                 this.writeArgs.UserToken = new AsyncUserToken
 73                 {
 74                     Socket = this.sock
 75                 };
 76             }
 77             if (block)
 78             {
 79                 this.sock.Connect(this.ServerIP, this.ServerPort);
 80                 if (this.sock.Connected)
 81                 {
 82                     // TCP客户端开始接受服务器发送的数据
 83                     this.readArgs.SetBuffer(0, this.receiveBufferCapacity);
 84                     if (!this.sock.ReceiveAsync(this.readArgs))
 85                     {
 86                         this.ProcessReceive(this.readArgs);
 87                     }
 88                 }
 89             }
 90             else
 91             {
 92                 this.connectArgs = new SocketAsyncEventArgs();
 93                 this.connectArgs.Completed += this.IO_Completed;
 94                 this.connectArgs.UserToken = new AsyncUserToken
 95                 {
 96                     Socket = this.sock
 97                 };
 98                 this.connectArgs.RemoteEndPoint = new IPEndPoint(IPAddress.Parse(this.ServerIP), this.ServerPort);
 99                 if (!this.sock.ConnectAsync(this.connectArgs))
100                 {
101                     this.ProcessConnect(this.connectArgs);
102                 }
103             }
104             return this.sock.Connected;
105         }
106 
107         /// <summary>
108         /// 关闭连接
109         /// </summary>
110         /// <param name="reuseSocket">如果关闭套接字允许重用套接字则为true</param>
111         public void Disconnect(bool reuseSocket)
112         {
113             if (this.sock == null)
114             {
115                 return;
116             }
117             if (this.sock.Connected)
118             {
119                 try
120                 {
121                     lock (this.sync_disconn)
122                     {
123                         this.sock.Shutdown(SocketShutdown.Both);
124                         this.sock.Disconnect(reuseSocket);
125                         this.sock.Close();
126                         this.sock = null;
127                     }
128                 }
129                 catch (SocketException)
130                 {
131                     this.sock = null;
132                 }
133                 catch (Exception)
134                 {
135                     this.sock = null;
136                 }
137             }
138         }
139 
140         public int Send(byte[] buffer)
141         {
142             if (this.sock == null || !this.sock.Connected)
143             {
144                 return 0;
145             }
146             return this.sock.Send(buffer);
147         }
148 
149         /// <summary>
150         /// 发送
151         /// </summary>
152         /// <param name="data">要发送的字符串</param>
153         /// <param name="bBlock">阻塞发送</param>
154         /// <returns></returns>
155         public int Send(string data, bool bBlock = true)
156         {
157             byte[] bytes = Encoding.Default.GetBytes(data);
158             if (bBlock)
159             {
160                 return this.sock.Send(bytes);
161             }
162             if (bytes.Length > this.writeBufferCapacity)
163             {
164                 this.writeBufferCapacity = bytes.Length;
165                 this.sendBuffer = new byte[this.writeBufferCapacity];
166             }
167             Array.Copy(bytes, this.sendBuffer, bytes.Length);
168             this.writeArgs.SetBuffer(0, bytes.Length);
169             if (!this.sock.SendAsync(this.writeArgs))
170             {
171                 this.ProcessSend(this.writeArgs);
172             }
173             return 0;
174         }
175 
176         private void IO_Completed(object sender, SocketAsyncEventArgs e)
177         {
178             SocketAsyncOperation lastOperation = e.LastOperation;
179             switch (lastOperation)
180             {
181             case SocketAsyncOperation.Connect:
182                 this.ProcessConnect(e);
183                 return;
184             case SocketAsyncOperation.Disconnect:
185                 break;
186             case SocketAsyncOperation.Receive:
187                 this.ProcessReceive(e);
188                 return;
189             default:
190                 if (lastOperation == SocketAsyncOperation.Send)
191                 {
192                     this.ProcessSend(e);
193                     return;
194                 }
195                 break;
196             }
197             throw new ArgumentException("The last operation completed on the socket was not a receive or send");
198         }
199 
200         /// <summary>
201         /// 处理接收到的数据
202         /// </summary>
203         /// <param name="e"></param>
204         private void ProcessReceive(SocketAsyncEventArgs e)
205         {
206             AsyncUserToken asyncUserToken = (AsyncUserToken)e.UserToken;
207             if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
208             {
209                 if (this.OnReceived != null)
210                 {
211                     this.OnReceived(this, e);
212                 }
213                 e.SetBuffer(e.Offset, this.receiveBufferCapacity);
214                 if (!asyncUserToken.Socket.ReceiveAsync(e))
215                 {
216                     this.ProcessReceive(e);
217                     return;
218                 }
219             }
220             else
221             {
222                 this.CloseClientSocket(e);
223             }
224         }
225 
226         /// <summary>
227         /// 发送完成后调用
228         /// </summary>
229         /// <param name="e"></param>
230         private void ProcessSend(SocketAsyncEventArgs e)
231         {
232             if (e.SocketError == SocketError.Success)
233             {
234                 if (this.OnSendCompleted != null)
235                 {
236                     this.OnSendCompleted(this, e);
237                     return;
238                 }
239             }
240             else
241             {
242                 this.CloseClientSocket(e);
243             }
244         }
245 
246         private void ProcessConnect(SocketAsyncEventArgs e)
247         {
248             if (e.SocketError == SocketError.Success)
249             {
250                 if (this.OnConnectCompleted != null)
251                 {
252                     this.OnConnectCompleted(this, e);
253                 }
254 
255                 this.readArgs.SetBuffer(0, this.receiveBufferCapacity);
256                 if (!this.sock.ReceiveAsync(this.readArgs))
257                 {
258                     this.ProcessReceive(this.readArgs);
259                     return;
260                 }
261             }
262             else if (e.SocketError == SocketError.ConnectionRefused || e.SocketError == SocketError.HostUnreachable || e.SocketError == SocketError.TimedOut)
263             {
264                 if (this.OnConnectCompleted != null)
265                 {
266                     this.OnConnectCompleted(this, e);
267                     return;
268                 }
269             }
270             else
271             {
272                 this.CloseClientSocket(e);
273             }
274         }
275 
276         private void CloseClientSocket(SocketAsyncEventArgs e)
277         {
278             if (this.OnConnectionClosed != null)
279             {
280                 this.OnConnectionClosed(this, e);
281             }
282             AsyncUserToken asyncUserToken = e.UserToken as AsyncUserToken;
283             try
284             {
285                 lock (this.sync_disconn)
286                 {
287                     if (this.sock != null)
288                     {
289                         this.sock.Shutdown(SocketShutdown.Send);
290                         this.sock.Close(200);
291                         this.sock = null;
292                     }
293                 }
294             }
295             catch (Exception){}
296             asyncUserToken.Socket = null;
297         }
298 
299         private void Dispose()
300         {
301             try
302             {
303                 // 关闭socket时,单独使用socket.close()通常会造成资源提前被释放,
304                 // 应该在关闭socket之前,先使用shutdown进行接受或者发送的禁用,再使用socket进行释放
305                 this.sock.Shutdown(SocketShutdown.Both);
306                 this.sock.Close();
307                 this.sock.Dispose();
308                 this.sock = null;
309             }
310             catch (Exception){}
311         }
312 
313         public string ServerIP { get; set; }
314 
315         public int ServerPort { get; set; }
316 
317         public byte[] ReceiveBuffer
318         {
319             get
320             {
321                 return this.receiveBuffer;
322             }
323         }
324 
325         public bool Connected
326         {
327             get
328             {
329                 return this.sock != null && this.sock.Connected;
330             }
331         }
332     }
333 }
  1 using System;
  2 using System.Collections.Generic;
  3 using System.Net;
  4 using System.Net.Sockets;
  5 using System.Threading;
  6 
  7 namespace JCommon.Net
  8 {
  9     public class SocketServer
 10     {
 11         public event EventHandler<SocketAsyncEventArgs> OnReceiveCompleted;
 12         public event EventHandler<SocketAsyncEventArgs> OnSendCompleted;
 13         public event EventHandler<SocketAsyncEventArgs> OnAccept;
 14         public event EventHandler<SocketAsyncEventArgs> OnConnectionBreak;
 15 
 16         private const int opsToPreAlloc = 2;                // 读,写(不为 接受连接 accepts 分配缓冲区空间)
 17         private int m_numConnections;                       // 同时处理的最大连接数
 18         private int m_receiveBufferSize;                    // 用于每个Socket I/O 操作的缓冲区大小
 19         private BufferManager m_bufferManager;              // 表示用于所有套接字操作的大量可重用的缓冲区
 20         private Socket listenSocket;                        // 用于监听传入的连接请求的套接字
 21         private SocketAsyncEventArgsPool m_readWritePool;   // 可重用SocketAsyncEventArgs对象池,用于写入,读取和接受套接字操作
 22         private List<SocketAsyncEventArgs> m_connectedPool;
 23         private int m_totalBytesRead;                       // 服务器接收的总共#个字节的计数器
 24         private int m_numConnectedSockets;                  // 连接到服务器的客户端总数
 25         private Semaphore m_maxNumberAcceptedClients;
 26 
 27         /// <summary>
 28         /// 创建服务端实例
 29         /// </summary>
 30         /// <param name="numConnections"></param>
 31         /// <param name="receiveBufferSize"></param>
 32         public SocketServer(int numConnections, int receiveBufferSize)
 33         {
 34             this.m_totalBytesRead = 0;
 35             this.m_numConnectedSockets = 0;
 36             this.m_numConnections = numConnections;
 37             this.m_receiveBufferSize = receiveBufferSize;
 38             this.m_bufferManager = new BufferManager(receiveBufferSize * numConnections * opsToPreAlloc, receiveBufferSize);
 39             this.m_readWritePool = new SocketAsyncEventArgsPool(numConnections);
 40             this.m_connectedPool = new List<SocketAsyncEventArgs>(numConnections);
 41         }
 42 
 43         /// <summary>
 44         /// 分配 SocketAsyncEventArg 对象池
 45         /// </summary>
 46         public void Init()
 47         {
 48             // 分配一个大字节缓冲区,所有 I/O 操作都使用该缓冲区。
 49             this.m_bufferManager.InitBuffer();
 50             for (int i = 0; i < this.m_numConnections; i++)
 51             {
 52                 // 分配可重用的 SocketAsyncEventArgs 对象
 53                 SocketAsyncEventArgs socketAsyncEventArgs = new SocketAsyncEventArgs();
 54                 socketAsyncEventArgs.Completed += this.IO_Completed;
 55                 socketAsyncEventArgs.UserToken = new AsyncUserToken();
 56 
 57                 // 将缓冲池中的字节缓冲区分配给 SocketAsyncEventArg 对象
 58                 this.m_bufferManager.SetBuffer(socketAsyncEventArgs);
 59 
 60                 // 放入对象池
 61                 this.m_readWritePool.Push(socketAsyncEventArgs);
 62             }
 63         }
 64 
 65         /// <summary>
 66         /// 启动服务器,侦听客户端连接请求
 67         /// </summary>
 68         /// <param name="localEndPoint"></param>
 69         public void Start(IPEndPoint localEndPoint)
 70         {
 71             try
 72             {
 73                 // 限制最大连接数
 74                 this.m_maxNumberAcceptedClients = new Semaphore(this.m_numConnections, this.m_numConnections);
 75 
 76                 // 创建 Socket 监听连接请求
 77                 this.listenSocket = new Socket(localEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
 78                 this.listenSocket.Bind(localEndPoint);
 79                 this.listenSocket.Listen(10);
 80 
 81                 // 接受客户端连接请求
 82                 this.StartAccept(null);
 83             }
 84             catch (Exception){}
 85         }
 86 
 87         public void Stop()
 88         {
 89             if (this.listenSocket == null)
 90             {
 91                 return;
 92             }
 93             try
 94             {
 95                 lock(m_connectedPool)
 96                 {
 97                     for (int i = 0; i < this.m_connectedPool.Count; i++)
 98                     {
 99                         this.CloseClientSocket(m_connectedPool[i]);
100                     }
101                     this.m_connectedPool.Clear();
102                 }
103                 this.listenSocket.LingerState = new LingerOption(true, 0);
104                 this.listenSocket.Close();
105                 this.listenSocket.Dispose();
106                 this.listenSocket = null;
107                 GC.Collect();
108             }
109             catch (Exception)
110             {
111             }
112         }
113 
114         public void Send(AsyncUserToken arg, byte[] msg)
115         {
116            SocketAsyncEventArgs argSend =  this.m_connectedPool.Find((s) => {
117                 AsyncUserToken userToken = s.UserToken as AsyncUserToken;
118                 return userToken.EndPort.ToString() == arg.EndPort.ToString();
119             });
120 
121            AsyncUserToken userToken1 = argSend.UserToken as AsyncUserToken;
122            userToken1.Socket.Send(msg);
123         }
124 
125         public void SendToAll(byte[] msg)
126         {
127             foreach(SocketAsyncEventArgs arg in this.m_connectedPool)
128             {
129                 AsyncUserToken userToken = arg.UserToken as AsyncUserToken;
130                 userToken.Socket.Send(msg);
131             }
132         }
133 
134         /// <summary>
135         /// 开始接受来自客户端的连接请求
136         /// </summary>
137         /// <param name="acceptEventArg"></param>
138         private void StartAccept(SocketAsyncEventArgs acceptEventArg)
139         {
140             if (acceptEventArg == null)
141             {
142                 acceptEventArg = new SocketAsyncEventArgs();
143                 acceptEventArg.Completed += this.AcceptEventArg_Completed;
144             }
145             else
146             {
147                 acceptEventArg.AcceptSocket = null;
148             }
149             this.m_maxNumberAcceptedClients.WaitOne();
150             if (this.listenSocket == null)
151             {
152                 return;
153             }
154             if (!this.listenSocket.AcceptAsync(acceptEventArg))
155             {
156                 this.ProcessAccept(acceptEventArg);
157             }
158         }
159 
160         /// <summary>
161         /// 接受连接请求完成后回调
162         /// </summary>
163         /// <param name="sender"></param>
164         /// <param name="e"></param>
165         private void AcceptEventArg_Completed(object sender, SocketAsyncEventArgs e)
166         {
167             this.ProcessAccept(e);
168         }
169 
170         private void ProcessAccept(SocketAsyncEventArgs e)
171         {
172             if (e.SocketError == SocketError.Success)
173             {
174                 Interlocked.Increment(ref this.m_numConnectedSockets);
175                 if (this.OnAccept != null)
176                 {
177                     this.OnAccept(null, e);
178                 }
179 
180                 // 获取接受的客户端连接的套接字
181                 SocketAsyncEventArgs socketAsyncEventArgs = this.m_readWritePool.Pop();
182                 AsyncUserToken userToken = socketAsyncEventArgs.UserToken as AsyncUserToken;
183                 userToken.Socket = e.AcceptSocket;
184                 userToken.ConnectTime = DateTime.Now;
185                 userToken.EndPort = e.AcceptSocket.RemoteEndPoint as IPEndPoint;
186 
187                 lock (m_connectedPool)
188                 {
189                     this.m_connectedPool.Add(socketAsyncEventArgs);
190                 }
191 
192                 if (!e.AcceptSocket.ReceiveAsync(socketAsyncEventArgs))
193                 {
194                     this.ProcessReceive(socketAsyncEventArgs);
195                 }
196 
197                 // 接受下一个连接请求
198                 this.StartAccept(e);
199             }
200             else
201             {
202                 this.Stop();
203             }
204         }
205 
206         /// <summary>
207         /// 每当套接字上的接收或发送操作完成时,就会调用此方法
208         /// </summary>
209         /// <param name="sender"></param>
210         /// <param name="e"></param>
211         private void IO_Completed(object sender, SocketAsyncEventArgs e)
212         {
213             switch (e.LastOperation)
214             {
215                 case SocketAsyncOperation.Receive:
216                     ProcessReceive(e);
217                     break;
218                 case SocketAsyncOperation.Send:
219                     ProcessSend(e);
220                     break;
221                 default:
222                     throw new ArgumentException("The last operation completed on the socket was not a receive or send");
223             }      
224         }
225 
226         /// <summary>
227         /// 异步接收操作完成后,将调用此方法。
228         /// </summary>
229         /// <param name="e"></param>
230         private void ProcessReceive(SocketAsyncEventArgs e)
231         {
232             AsyncUserToken asyncUserToken = (AsyncUserToken)e.UserToken;
233             if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
234             {
235                 Interlocked.Add(ref this.m_totalBytesRead, e.BytesTransferred);
236                 if (this.OnReceiveCompleted != null)
237                 {
238                     this.OnReceiveCompleted(this, e);
239                 }
240                 e.SetBuffer(e.Offset, this.m_receiveBufferSize);
241                 if (!asyncUserToken.Socket.ReceiveAsync(e))
242                 {
243                     this.ProcessReceive(e);
244                     return;
245                 }
246             }
247             else
248             {
249                 this.CloseClientSocket(e);
250             }
251         }
252 
253         /// <summary>
254         /// 异步发送操作完成后,将调用此方法。
255         /// 该方法在套接字上发出另一个接收,以读取从客户端发送的所有其他数据
256         /// </summary>
257         /// <param name="e"></param>
258         private void ProcessSend(SocketAsyncEventArgs e)
259         {
260             if (e.SocketError == SocketError.Success)
261             {
262                 if (this.OnSendCompleted != null)
263                 {
264                     this.OnSendCompleted(null, e);
265                 }
266                 AsyncUserToken asyncUserToken = (AsyncUserToken)e.UserToken;
267                 if (!asyncUserToken.Socket.ReceiveAsync(e))
268                 {
269                     this.ProcessReceive(e);
270                     return;
271                 }
272             }
273             else
274             {
275                 this.CloseClientSocket(e);
276             }
277         }
278 
279         private void CloseClientSocket(SocketAsyncEventArgs e)
280         {
281             if (this.OnConnectionBreak != null)
282             {
283                 this.OnConnectionBreak(null, e);
284             }
285             AsyncUserToken asyncUserToken = e.UserToken as AsyncUserToken;
286             if (asyncUserToken != null && asyncUserToken.Socket != null)
287             {
288                 try
289                 {
290                     asyncUserToken.Socket.Shutdown(SocketShutdown.Both);
291                     asyncUserToken.Socket.Disconnect(false);
292                     asyncUserToken.Socket.Close();
293                     asyncUserToken.Socket = null;
294                 }
295                 catch (Exception)
296                 {
297                 }
298                 finally
299                 {
300                     Interlocked.Decrement(ref this.m_numConnectedSockets);
301                     this.m_maxNumberAcceptedClients.Release();
302                     this.m_readWritePool.Push(e);
303                     lock (m_connectedPool)
304                     {
305                         this.m_connectedPool.Remove(e);
306                     }
307                 }
308             }
309         }
310     }
311 }
原文地址:https://www.cnblogs.com/jshchg/p/12931668.html