/// <summary> /// Resolves local IP to public IP using STUN. /// </summary> /// <param name="stunServer">STUN server.</param> /// <param name="port">STUN server port. Default port is 3478.</param> /// <param name="localIP">Local IP address.</param> /// <returns>Returns public IP address.</returns> /// <exception cref="ArgumentNullException">Is raised when <b>stunServer</b> or <b>localIP</b> is null reference.</exception> /// <exception cref="ArgumentException">Is raised when any of the arguments has invalid value.</exception> /// <exception cref="IOException">Is raised when no connection to STUN server.</exception> public static IPAddress GetPublicIP(string stunServer, int port, IPAddress localIP) { if (stunServer == null) { throw new ArgumentNullException(nameof(stunServer)); } if (stunServer == string.Empty) { throw new ArgumentException(@"Argument 'stunServer' value must be specified."); } if (port < 1) { throw new ArgumentException(@"Invalid argument 'port' value."); } if (localIP == null) { throw new ArgumentNullException(nameof(localIP)); } if (!NetUtils.IsPrivateIP(localIP)) { return(localIP); } var result = Query(stunServer, port, NetUtils.CreateSocket(new IPEndPoint(localIP, 0), ProtocolType.Udp)); if (result.PublicEndPoint != null) { return(result.PublicEndPoint.Address); } throw new IOException(@"Failed to STUN public IP address. STUN server name is invalid or firewall blocks STUN."); }
/// <summary> /// Initialize and start the server. /// </summary> public void Start() { if (this._isRunning) { throw new InvalidOperationException("Server is already running."); } if (this.Configuration.Port <= 0) { throw new EtherConfigurationException($"{this.Configuration.Port} is not a valid port."); } var address = this.Configuration.Address; if (address == null) { throw new EtherConfigurationException($"Invalid host : {this.Configuration.Host}"); } if (this._readPool == null) { this._readPool = new SocketAsyncEventArgsPool(); for (int i = 0; i < this.Configuration.MaximumNumberOfConnections; i++) { this._readPool.Push(NetUtils.CreateSocket(this.Configuration.BufferSize, this.IO_Completed)); } } if (this._writePool == null) { this._writePool = new SocketAsyncEventArgsPool(); for (int i = 0; i < this.Configuration.MaximumNumberOfConnections; i++) { this._writePool.Push(NetUtils.CreateSocket(this.Configuration.BufferSize, this.IO_Completed)); } } this.Initialize(); this.Socket.Bind(new IPEndPoint(address, this.Configuration.Port)); this.Socket.Listen(this.Configuration.Backlog); Task.Factory.StartNew(this.ProcessSendQueue); this.StartAccept(); this._isRunning = true; this._resetEvent.WaitOne(); }