• 使用完成端口(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 }
  • 相关阅读:
    nuget
    C#枚举中使用Flags特性
    情感分析
    docker
    core部署
    脱壳系列_2_IAT加密壳_详细分析(含脚本)
    安全公司-* * * *-面试题:_ 安卓逆向分析分享
    18_ShadowWalker
    17_页面异常接管
    16_TLB与流水线
  • 原文地址:https://www.cnblogs.com/jshchg/p/12931668.html
Copyright © 2020-2023  润新知