protected override void DoBind(EndPoint localAddress) { if (!this.Open) { return; } Debug.Assert(this.EventLoop.InEventLoop); if (!this.IsInState(StateFlags.Active)) { var address = (IPEndPoint)localAddress; var loopExecutor = (LoopExecutor)this.EventLoop; uint flags = PlatformApi.GetAddressFamily(address.AddressFamily); this.tcpListener = new TcpListener(loopExecutor.UnsafeLoop, flags); // Apply the configuration right after the tcp handle is created // because SO_REUSEPORT cannot be configured after bind this.config.Apply(); this.tcpListener.Bind(address); this.isBound = true; this.tcpListener.Listen((TcpServerChannelUnsafe)this.Unsafe, this.config.Backlog); this.CacheLocalAddress(); this.SetState(StateFlags.Active); } }
protected override void DoClose() { if (this.TryResetState(StateFlags.Open | StateFlags.Active)) { this.tcpListener?.CloseHandle(); this.tcpListener = null; } }
static void SetReusePort(TcpListener listener, int value) { try { PlatformApi.SetReusePort(listener, value); } catch (ObjectDisposedException ex) { ThrowHelper.ThrowChannelException(ex); } catch (SocketException ex) { ThrowHelper.ThrowChannelException(ex); } }
static void SetReuseAddress(TcpListener listener, int value) { try { PlatformApi.SetReuseAddress(listener, value); } catch (ObjectDisposedException ex) { throw new ChannelException(ex); } catch (SocketException ex) { throw new ChannelException(ex); } }