/// <summary> /// 处理连接请求 /// </summary> /// <param name="acceptContext">与完成Accept操作关联的SocketAsyncEventArg对象</param> private void ProcessAccept(SocketAsyncEventArgs acceptContext) { // 1.新的连接 Socket acceptSocket = acceptContext.AcceptSocket; if (acceptSocket != null && acceptContext.SocketError == SocketError.Success) { try { // 从对象池中取出一个用于读取的SocketAsyncEventArgs对象,将连接到的Socket客户端放入UserToken SocketAsyncEventArgs readEventArgs = _poolOfReadWriteEventArgs.Pop(); if (readEventArgs == null) { Trace.WriteLine(string.Format("连接数已满,拒绝 {0} 的连接请求。", acceptSocket.RemoteEndPoint)); acceptSocket.Close(); return; } readEventArgs.Completed += SocketAsyncEventArgs_IOCompleted; ITcpClientProxy clientHandler = null; #region 处理连接信息 if (CreateClientHandler != null) { clientHandler = CreateClientHandler(acceptSocket, Setting); clientHandler.FeedbackTime = DateTime.Now; clientHandler.ReceiveContext = readEventArgs; clientHandler.ClientStatus = (int)ClientStateEnums.Connected; } #endregion //将连接SAEA侦听到的Socket传递给用于收发的SAEA readEventArgs.AcceptSocket = acceptSocket; readEventArgs.UserToken = clientHandler; // 增加连接数 if (clientHandler != null) { _clientMembers.Add(clientHandler); } _logger.Info(string.Format("{0} {1}连接上教师机, 目前服务器上有{2}个连接。", DateTime.Now.ToString("HH:mm:ss"), acceptSocket.RemoteEndPoint, this.ConnectedCount)); // 通知外部,有新的连接 OnClientConnected(readEventArgs); // 开始侦听该连接传入的数据 this.StartReceive(readEventArgs); } catch (Exception ex) { Console.WriteLine("连接时发生错误:" + ex.StackTrace); _logger.Error("接收连接时错误:" + ex.StackTrace); } } else { //Close方法关闭并释放所有资源(托管和非托管), 内部调用了Dispose if (acceptSocket != null) { acceptSocket.Close(); } _semaphoreAcceptedClients.Release(); } #region 最后的处理,接收下个连接 // 开始接收新的连接(而不是立即重用当前的acceptContext,以提升性能) this.StartAccept(); // 将SAEA对象放回连接池,以便重用 acceptContext.Completed -= this.SocketAsyncEventArgs_IOCompleted; acceptContext.AcceptSocket = null; // 2015-05-20 _poolOfAcceptEventArgs.Push(acceptContext); #endregion }
/// <summary> /// 停止侦听服务. /// </summary> public void Stop() { _logger.Info("主动关闭TCP, 断开接连。"); // 先通知所有客户端断开 if (_clientMembers != null) { for (int index = _clientMembers.Count - 1; index >= 0; index--) { var clientHandler = _clientMembers[index]; try { if (this.ClientDisconnected != null) { ClientStateEventArgs stateObject = new ClientStateEventArgs(clientHandler.ReceiveContext); stateObject.ClientStatus = ClientStateEnums.Closed; this.ClientDisconnected(this, stateObject); } //_clientHandlers.Remove(clientHandler); } catch (Exception ex) { // 外部未处理的异常,记录日志,不影响主流程。 _logger.Error(ex.StackTrace); } //this.RecycleContext(clientHandler.ReceiveContext); } } lock (_tcpLock) { // 1.pulse thread close this.StopCheckingPulse(); // 清理缓存,事件 SocketAsyncEventArgs eventArgs; while (this._poolOfAcceptEventArgs.Count > 0) { eventArgs = _poolOfAcceptEventArgs.Pop(); eventArgs.Completed -= SocketAsyncEventArgs_IOCompleted; //_bufferManager.FreeBuffer(eventArgs); eventArgs.Dispose(); } while (this._poolOfReadWriteEventArgs.Count > 0) { eventArgs = _poolOfReadWriteEventArgs.Pop(); eventArgs.Completed -= SocketAsyncEventArgs_IOCompleted; _bufferManager.FreeBuffer(eventArgs); eventArgs.Dispose(); } _bufferManager = null; //GC.Collect(); try { //_socketListener.Disconnect(true); //_socketListener.Shutdown(SocketShutdown.Both); } catch (Exception ex) { _logger.Error(ex.StackTrace); } finally { if (_socketListener != null) { _socketListener.Close(); _socketListener.Dispose(); _socketListener = null; } } mutex.ReleaseMutex(); this._semaphoreAcceptedClients.Release(); // 清掉当前客户端 foreach (var client in _clientMembers) { Socket s = client.Connection; try { s.Close(); //s.Shutdown(SocketShutdown.Receive); //s.Disconnect(true); } catch (Exception) { } finally { if (s.Connected) { s.Close(); s.Dispose(); } s = null; } } _clientMembers.Clear(); } }