/// <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(); }