/// <summary> /// /// </summary> /// <param name="e"></param> private void ProcessSend(SocketAsyncEventArgs e) { AsyncSocketUserTokenEventArgs token = (AsyncSocketUserTokenEventArgs)e.UserToken; Interlocked.Add(ref _totalBytesWrite, e.BytesTransferred); if (e.Count > _bufferSize) { lock (_bufferLock) { _bufferManager.SetBuffer(e); } } lock (_writePool) { _writePool.Push(e); } e.UserToken = null; if (e.SocketError == SocketError.Success) { Debug.WriteLine(string.Format(AsyncSocketServerConstants.ServerSendTotalBytesStringFormat, e.BytesTransferred.ToString())); this.OnDataSent(token); } else { this.RaiseDisconnectedEvent(token); } }
/// <summary> /// /// </summary> /// <param name="token"></param> private void CloseClientSocket(AsyncSocketUserTokenEventArgs token) { try { token.Socket.Shutdown(SocketShutdown.Both); token.Socket.Close(); } catch (ObjectDisposedException) { } catch (SocketException) { token.Socket.Close(); } catch (Exception ex) { token.Socket.Close(); Debug.WriteLine(string.Format(AsyncSocketServerConstants.DebugStringFormat, ex.Message)); throw; } finally { Interlocked.Decrement(ref _numConnectedSockets); this._maxNumberAcceptedClients.Release(); Debug.WriteLine(string.Format(AsyncSocketServerConstants.ClientConnectionStringFormat, _numConnectedSockets.ToString())); lock (_readPool) { _readPool.Push(token.ReadEventArgs); } } }
private void InitializePool() { this._bufferManager = new AsyncSocketServerEventArgsBufferManager(_bufferSize * _numConnections * AsyncSocketServerConstants.OpsToPreAlloc, _bufferSize); this._readPool = new AsyncSocketServerEventArgsPool(_numConnections); this._writePool = new AsyncSocketServerEventArgsPool(_numConnections); this._tokens = new Dictionary <Guid, AsyncSocketUserTokenEventArgs>(); this._maxNumberAcceptedClients = new Semaphore(_numConnections, _numConnections); this._bufferManager.InitBuffer(); SocketAsyncEventArgs readWriteEventArg; AsyncSocketUserTokenEventArgs token; /// Initialize read Pool for (int i = 0; i < _numConnections; i++) { token = new AsyncSocketUserTokenEventArgs(); token.ReadEventArgs.Completed += new EventHandler <SocketAsyncEventArgs>(IO_Completed); this._bufferManager.SetBuffer(token.ReadEventArgs); token.SetBuffer(token.ReadEventArgs.Buffer, token.ReadEventArgs.Offset); this._readPool.Push(token.ReadEventArgs); } /// Initialize write Pool for (int i = 0; i < _numConnections; i++) { readWriteEventArg = new SocketAsyncEventArgs(); readWriteEventArg.Completed += new EventHandler <SocketAsyncEventArgs>(IO_Completed); readWriteEventArg.UserToken = null; this._bufferManager.SetBuffer(readWriteEventArg); this._writePool.Push(readWriteEventArg); } }
/// <summary> /// Connect to remote endpoint /// </summary> /// <param name="remoteEndPoint">Remote IPEndPoint</param> /// <param name="useIOCP">Specifies whether the socket should only use Overlapped I/O mode.</param> public void Connect(IPEndPoint remoteEndPoint, bool useIOCP = true) { this._clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { this._token = new AsyncSocketUserTokenEventArgs(this._clientSocket); this._token.ConnectionId = Guid.NewGuid(); this._token.SetBuffer(this._token.ReadEventArgs.Buffer, this._token.ReadEventArgs.Offset); this._clientSocket.UseOnlyOverlappedIO = useIOCP; this._clientSocket.BeginConnect(remoteEndPoint, new AsyncCallback(this.ProcessConnect), this._clientSocket); Debug.WriteLine(AsyncSocketClientConstants.ClientConnectSuccessfully); } catch (ObjectDisposedException e) { Debug.WriteLine(string.Format(AsyncSocketClientConstants.ClientConnectExceptionStringFormat, e.Message)); this.OnDisconnected(new AsyncSocketUserTokenEventArgs(this._clientSocket)); } catch (SocketException e) { Debug.WriteLine(string.Format(AsyncSocketClientConstants.ClientConnectExceptionStringFormat, e.Message)); if (e.ErrorCode == (int)SocketError.ConnectionReset) { this.OnDisconnected(this._token); } Debug.WriteLine(string.Format(AsyncSocketClientConstants.DebugStringFormat, e.Message)); this.OnErrorOccurred(this._token.Socket, new AsyncSocketErrorEventArgs(e.Message, e, AsyncSocketErrorCodeEnum.ClientConnectException)); } }
/// <summary> /// /// </summary> /// <param name="e"></param> protected virtual void OnDisconnected(AsyncSocketUserTokenEventArgs e) { // Copy a reference to the delegate field now into a temporary field for thread safety EventHandler <AsyncSocketUserTokenEventArgs> temp = Interlocked.CompareExchange(ref Disconnected, null, null); if ((temp != null) && (e.EndPoint != null)) { temp(this, e); } }
/// <summary> /// /// </summary> /// <param name="e"></param> private void ProcessReceive(SocketAsyncEventArgs e) { AsyncSocketUserTokenEventArgs token = (AsyncSocketUserTokenEventArgs)e.UserToken; if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success) { Interlocked.Add(ref _totalBytesRead, e.BytesTransferred); Debug.WriteLine(string.Format(AsyncSocketServerConstants.ServerReceiveTotalBytesStringFormat, this._totalBytesRead.ToString())); token.SetBytesReceived(e.BytesTransferred); this.OnDataReceived(token); try { bool willRaiseEvent = token.Socket.ReceiveAsync(e); if (!willRaiseEvent) { this.ProcessReceive(e); } } catch (ObjectDisposedException) { this.RaiseDisconnectedEvent(token); } catch (SocketException socketException) { if (socketException.ErrorCode == (int)SocketError.ConnectionReset) { this.RaiseDisconnectedEvent(token); } else { this.OnErrorOccurred(token, new AsyncSocketErrorEventArgs(AsyncSocketServerConstants.SocketReceiveException, socketException)); } } catch (Exception ex) { Debug.WriteLine(string.Format(AsyncSocketServerConstants.DebugStringFormat, ex.Message)); throw; } } else { this.RaiseDisconnectedEvent(token); } }
/// <summary> /// /// </summary> /// <param name="token"></param> private void RaiseDisconnectedEvent(AsyncSocketUserTokenEventArgs token) { if (null != token) { lock (((ICollection)this._tokens).SyncRoot) { if (this._tokens.ContainsValue(token)) { this._tokens.Remove(token.ConnectionId); this.CloseClientSocket(token); if (null != token) { this.OnDisconnected(token); } } } } }