/// <summary> /// 移除客户端并关闭连接 /// </summary> /// <param name="clientID">客户端ID</param> /// <exception cref="断开连接的Socket异常"></exception> private void DropClient(string clientID) { if (clientList.ContainsKey(clientID)) { var client = clientList[clientID]; //从客户端列表中移除 clientLocker.EnterWriteLock(); try { clientList.Remove(clientID); } finally { clientLocker.ExitWriteLock(); } //减少计数器 Interlocked.Decrement(ref currentConnectedNumber); if (client.IsClientAdd) { //通知客户端移除 SendNotifyData(false, client.PlayerName); } //断开连接 try { client.ClientSocket.Shutdown(SocketShutdown.Both); } catch (Exception ex) { ErrorLogger.LogException(ex); //throw new Exception("断开客户端:" + clientID + " 时出现问题,详细请查看错误日志"); } client.ClientSocket.Close(); //释放资源 //设置为空以避免在回调函数ProcessReceives当中执行 client.revcEventArg.UserToken = null; argsPool.Push(client.revcEventArg); argsPool.Push(client.sendEventArg); //这个很关键,要不服务器满员了之后,就不会接受连接了 semaphoreAcceptedClients.Release(); client = null; } }
private void initServer() { var accept = maxConnection + 1; //建立缓存池,包括读写,缓存池的大小为最大连接数×数据包大小×2(2表示读写两个) bufferManager = new BufferPool(accept * bufferSize * opsToPreAlloc, bufferSize); //同样建立读写参数池 argsPool = new SocketArgsPool(accept * opsToPreAlloc); //根据最大连接数建立Semaphore semaphoreAcceptedClients = new Semaphore(accept, accept); //预分配数据发送接收参数 SocketAsyncEventArgs rsArgs; for (var i = 0; i < accept * opsToPreAlloc; i++) { rsArgs = new SocketAsyncEventArgs(); rsArgs.Completed += IOCompleted; bufferManager.SetBuffer(rsArgs); argsPool.Push(rsArgs); } //接受连接参数 AcceptArg = new SocketAsyncEventArgs(); AcceptArg.Completed += SocketAccepted; }