Exemplo n.º 1
0
        /// <summary>
        ///     Start this listener
        /// </summary>
        /// <param name="address">Address to accept connections on</param>
        /// <param name="port">Port to use. Set to <c>0</c> to let the OS decide which port to use. </param>
        /// <seealso cref="LocalPort" />
        public virtual void Start(IPAddress address, int port)
        {
            if (port < 0)
            {
                throw new ArgumentOutOfRangeException("port", port, "Port must be 0 or more.");
            }
            if (_listener != null)
            {
                throw new InvalidOperationException("Already listening.");
            }


            _listener = new TcpListener(address, port);
            _listener.Start();

            for (int i = 0; i < 20; i++)
            {
                var decoder = _configuration.DecoderFactory();
                var encoder = _configuration.EncoderFactory();
                var channel = _channelFactory.Create(_bufferPool.Pop(), encoder, decoder);
                _channels.Push(channel);
            }

            _listener.BeginAcceptSocket(OnSocket, null);
        }
        //private void OnAccept(object sender, SocketAsyncEventArgs e)
        //{
        //    if (e.SocketError != SocketError.Success)
        //    {
        //        this.shutdown.Set();
        //        return;
        //    }
        //    Interlocked.Increment(ref this.numConnectedSockets);

        //    ServerClientContext context;
        //    if (!this.contexts.TryPop(out context))
        //        throw new InvalidOperationException("Failed to get a new client context, all is currently in use.");

        //    if (!this.ValidateClient(e.AcceptSocket))
        //    {
        //        try
        //        {
        //            e.AcceptSocket.Shutdown(SocketShutdown.Send);
        //        }
        //        catch
        //        {
        //        }
        //        e.AcceptSocket.Dispose();
        //        return;
        //    }

        //    var client = this.CreateClient(e.AcceptSocket.RemoteEndPoint);
        //    context.Assign(e.AcceptSocket, client);
        //    this.OnClientConnected(context);

        //    this.StartAccept();
        //}

        private void OnAcceptSocket(object sender, SocketAsyncEventArgs e)
        {
            if (_shuttingDown)
            {
                return;
            }

            try
            {
                // Required as _listener.Stop() disposes the underlying socket
                // thus causing an objectDisposedException here.
                var socket = e.AcceptSocket;

                ITcpChannel channel;
                if (!_channels.TryPop(out channel))
                {
                    var decoder = _configuration.DecoderFactory();
                    var encoder = _configuration.EncoderFactory();
                    channel = _channelFactory.Create(_bufferPool.Pop(), encoder, decoder);
                }

                channel.Disconnected    = OnChannelDisconnect;
                channel.MessageReceived = OnMessage;
                channel.Assign(socket);

                var args = OnClientConnected(channel);
                if (!args.MayConnect)
                {
                    if (args.Response != null)
                    {
                        channel.Send(args.Response);
                    }
                    channel.Close();
                    return;
                }
            }
            catch (Exception exception)
            {
                ListenerError(this, new ErrorEventArgs(exception));
            }


            this.StartAccept();
        }