/// <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);
            }
        }
Beispiel #4
0
        /// <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);
                        }
                    }
                }
            }
        }