Ejemplo n.º 1
0
        /// <summary>
        /// Try to send pending data
        /// </summary>
        private void TrySend()
        {
            if (!IsConnected)
            {
                return;
            }

            if (!_sendEventArg.Lock())
            {
                return;
            }

            try
            {
                // Async send with the send handler
                _sendEventArg.RemoteEndPoint = _sendEndpoint;
                _sendEventArg.SetBuffer(_sendBuffer.Array, _sendBuffer.Offset, _sendBuffer.Count);
                if (!Socket.SendToAsync(_sendEventArg))
                {
                    OnAsyncCompleted(null, _sendEventArg);
                }
            }
            catch (ObjectDisposedException)
            {
                _sendEventArg.Unlock();
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Start the server (synchronous)
        /// </summary>
        /// <returns>'true' if the server was successfully started, 'false' if the server failed to start</returns>
        public virtual bool Start()
        {
            if (IsStarted)
            {
                return(false);
            }

            // Setup event args
            _receiveEventArg = new SocketArgs(SocketAsyncOperation.Receive);
            _receiveEventArg.SetBuffer(new byte[OptionReceiveBufferSize], 0, OptionReceiveBufferSize);
            _receiveEventArg.Completed += OnAsyncCompleted;
            _sendEventArg            = new SocketArgs(SocketAsyncOperation.Send);
            _sendEventArg.Completed += OnAsyncCompleted;

            // Create a new server socket
            Socket = CreateSocket();

            // Apply the option: reuse address
            Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, OptionReuseAddress);
            // Apply the option: exclusive address use
            Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse, OptionExclusiveAddressUse);
            // Apply the option: dual mode (this option must be applied before recieving)
            if (Socket.AddressFamily == AddressFamily.InterNetworkV6)
            {
                Socket.DualMode(OptionDualMode);
            }

            // Bind the server socket to the IP endpoint
            Socket.Bind(Endpoint);
            // Refresh the endpoint property based on the actual endpoint created
            Endpoint = (IPEndPoint)Socket.LocalEndPoint;

            // Call the server starting handler
            OnStarting();

            // Prepare receive endpoint
            _receiveEndpoint = new IPEndPoint((Endpoint.AddressFamily == AddressFamily.InterNetworkV6) ? IPAddress.IPv6Any : IPAddress.Any, 0);

            // Reset statistic
            BytesPending      = 0;
            BytesSending      = 0;
            BytesSent         = 0;
            BytesReceived     = 0;
            DatagramsSent     = 0;
            DatagramsReceived = 0;

            // Update the started flag
            IsStarted = true;

            // Call the server started handler
            OnStarted();

            return(true);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Try to send pending data
        /// </summary>
        private void TrySend()
        {
            if (!IsConnected)
            {
                Release();
                return;
            }

            if (!_sendEventArg.Lock())
            {
                return;
            }

            // Update statistic
            BytesPending  = 0;
            BytesSending += _sendQueue.Count;

            if (_sendQueue.IsEmpty)
            {
                _sendEventArg.Unlock();

                if (!IsConnected)
                {
                    Release();
                }

                OnEmpty();

                return;
            }

            try
            {
                // Async send with the send handler
                ArraySegment <byte> buffer;
                _sendQueue.TryDequeue(out buffer);
                _sendEventArg.SetBuffer(buffer.Array, buffer.Offset, buffer.Count);
                if (!Socket.SendAsync(_sendEventArg))
                {
                    OnAsyncCompleted(null, _sendEventArg);
                }
            }
            catch (ObjectDisposedException)
            {
                _sendEventArg.Unlock();
                Release();
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Connect the client (asynchronous)
        /// </summary>
        /// <returns>'true' if the client was successfully connected, 'false' if the client failed to connect</returns>
        public virtual bool ConnectAsync()
        {
            if (IsConnected || IsConnecting)
            {
                return(false);
            }

            // Setup event args
            _connectEventArg = new SocketAsyncEventArgs();
            _connectEventArg.RemoteEndPoint = Endpoint;
            _connectEventArg.Completed     += OnAsyncCompleted;
            _receiveEventArg = new SocketArgs(SocketAsyncOperation.Receive);
            _receiveEventArg.SetBuffer(new byte[OptionReceiveBufferSize], 0, OptionReceiveBufferSize);
            _receiveEventArg.Completed += OnAsyncCompleted;
            _sendEventArg            = new SocketArgs(SocketAsyncOperation.Send);
            _sendEventArg.Completed += OnAsyncCompleted;

            // Create a new client socket
            Socket = CreateSocket();

            // Apply the option: dual mode (this option must be applied before connecting)
            if (Socket.AddressFamily == AddressFamily.InterNetworkV6)
            {
                Socket.DualMode(OptionDualMode);
            }

            // Update the connecting flag
            IsConnecting = true;

            // Call the client connecting handler
            OnConnecting();

            // Async connect to the server
            if (!Socket.ConnectAsync(_connectEventArg))
            {
                ProcessConnect(_connectEventArg);
            }

            return(true);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Connect the client (synchronous)
        /// </summary>
        /// <returns>'true' if the client was successfully connected, 'false' if the client failed to connect</returns>
        public virtual bool Connect()
        {
            if (IsConnected)
            {
                return(false);
            }

            // Setup event args
            _receiveEventArg = new SocketArgs(SocketAsyncOperation.Receive);
            _receiveEventArg.SetBuffer(new byte[OptionReceiveBufferSize], 0, OptionReceiveBufferSize);
            _receiveEventArg.Completed += OnAsyncCompleted;
            _sendEventArg            = new SocketArgs(SocketAsyncOperation.Send);
            _sendEventArg.Completed += OnAsyncCompleted;

            // Create a new client socket
            Socket = CreateSocket();

            // Apply the option: reuse address
            Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, OptionReuseAddress);
            // Apply the option: exclusive address use
            Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse, OptionExclusiveAddressUse);
            // Apply the option: dual mode (this option must be applied before recieving/sending)
            if (Socket.AddressFamily == AddressFamily.InterNetworkV6)
            {
                Socket.DualMode(OptionDualMode);
            }

            // Call the client connecting handler
            OnConnecting();

            try
            {
                // Bind the acceptor socket to the IP endpoint
                if (OptionMulticast)
                {
                    Socket.Bind(Endpoint);
                }
                else
                {
                    var endpoint = new IPEndPoint((Endpoint.AddressFamily == AddressFamily.InterNetworkV6) ? IPAddress.IPv6Any : IPAddress.Any, 0);
                    Socket.Bind(endpoint);
                }
            }
            catch (SocketException ex)
            {
                // Call the client error handler
                SendError("Connect", ex.SocketErrorCode);

                // Reset event args
                _receiveEventArg.Completed -= OnAsyncCompleted;
                _sendEventArg.Completed    -= OnAsyncCompleted;

                // Call the client disconnecting handler
                OnDisconnecting();

                // Close the client socket
                Socket.Close();

                // Dispose the client socket
                Socket.Dispose();

                // Dispose event arguments
                _receiveEventArg.Dispose();
                _sendEventArg.Dispose();

                // Call the client disconnected handler
                OnDisconnected();

                return(false);
            }

            // Prepare receive endpoint
            _receiveEndpoint = new IPEndPoint((Endpoint.AddressFamily == AddressFamily.InterNetworkV6) ? IPAddress.IPv6Any : IPAddress.Any, 0);

            // Reset statistic
            BytesPending      = 0;
            BytesSending      = 0;
            BytesSent         = 0;
            BytesReceived     = 0;
            DatagramsSent     = 0;
            DatagramsReceived = 0;

            // Update the connected flag
            IsConnected = true;

            // Call the client connected handler
            OnConnected();

            return(true);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Connect the client (synchronous)
        /// </summary>
        /// <remarks>
        /// Please note that synchronous connect will not receive data automatically!
        /// You should use Receive() or ReceiveAsync() method manually after successful connection.
        /// </remarks>
        /// <returns>'true' if the client was successfully connected, 'false' if the client failed to connect</returns>
        public virtual bool Connect()
        {
            if (IsConnected || IsConnecting)
            {
                return(false);
            }

            // Setup event args
            _connectEventArg = new SocketAsyncEventArgs();
            _connectEventArg.RemoteEndPoint = Endpoint;
            _connectEventArg.Completed     += OnAsyncCompleted;
            _receiveEventArg = new SocketArgs(SocketAsyncOperation.Receive);
            _receiveEventArg.SetBuffer(new byte[OptionReceiveBufferSize], 0, OptionReceiveBufferSize);
            _receiveEventArg.Completed += OnAsyncCompleted;
            _sendEventArg            = new SocketArgs(SocketAsyncOperation.Send);
            _sendEventArg.Completed += OnAsyncCompleted;

            // Create a new client socket
            Socket = CreateSocket();

            // Apply the option: dual mode (this option must be applied before connecting)
            if (Socket.AddressFamily == AddressFamily.InterNetworkV6)
            {
                Socket.DualMode(OptionDualMode);
            }

            // Call the client connecting handler
            OnConnecting();

            try
            {
                // Connect to the server
                Socket.Connect(Endpoint);
            }
            catch (SocketException ex)
            {
                // Call the client error handler
                SendError("Connect", ex.SocketErrorCode);

                // Reset event args
                _connectEventArg.Completed -= OnAsyncCompleted;
                _receiveEventArg.Completed -= OnAsyncCompleted;
                _sendEventArg.Completed    -= OnAsyncCompleted;

                // Call the client disconnecting handler
                OnDisconnecting();

                // Close the client socket
                Socket.Close();

                // Dispose the client socket
                Socket.Dispose();

                // Dispose event arguments
                _connectEventArg.Dispose();
                _receiveEventArg.Dispose();
                _sendEventArg.Dispose();

                // Call the client disconnected handler
                OnDisconnected();

                return(false);
            }

            // Apply the option: keep alive (keepAliveTime = 10min, keepAliveInterval = 60s)
            if (OptionKeepAlive)
            {
                Socket.SetKeepAlive(600, 60);
            }
            // Apply the option: no delay
            if (OptionNoDelay)
            {
                Socket.NoDelay = true;
            }

            // Reset statistic
            BytesPending  = 0;
            BytesSending  = 0;
            BytesSent     = 0;
            BytesReceived = 0;

            // Update the connected flag
            IsConnected = true;

            // Call the client connected handler
            OnConnected();

            // Call the empty send buffer handler
            if (_sendQueue.IsEmpty)
            {
                OnEmpty();
            }

            return(true);
        }