Найдите следующий TCP-порт in.Net
Я хочу создать новую сеть.tcp:/ / localhost: x / Service endpoint для вызова службы WCF с динамически назначенным новым открытым tcp-портом.
Я знаю, что TcpClient назначит новый порт на стороне клиента, когда я открою соединение с данным сервером.
есть ли простой способ найти следующий открытый TCP-порт в .Net?
Мне нужно фактическое число, так что я могу построить строку выше, 0 не работает, так как мне нужно передать эту строку в другой процесс, так что что я могу перезвонить по этому новому каналу.
6 ответов:
вот что я искала:
static int FreeTcpPort() { TcpListener l = new TcpListener(IPAddress.Loopback, 0); l.Start(); int port = ((IPEndPoint)l.LocalEndpoint).Port; l.Stop(); return port; }
Сначала откройте порт, а затем укажите правильный номер порта для другого процесса.
в противном случае все еще возможно, что какой-то другой процесс сначала открывает порт, и у вас все еще есть другой.
Если вы просто хотите дать начальный порт, и пусть он вернет вам следующий доступный tcp-порт, используйте такой код:
public static int GetAvailablePort(int startingPort) { var portArray = new List<int>(); var properties = IPGlobalProperties.GetIPGlobalProperties(); // Ignore active connections var connections = properties.GetActiveTcpConnections(); portArray.AddRange(from n in connections where n.LocalEndPoint.Port >= startingPort select n.LocalEndPoint.Port); // Ignore active tcp listners var endPoints = properties.GetActiveTcpListeners(); portArray.AddRange(from n in endPoints where n.Port >= startingPort select n.Port); // Ignore active udp listeners endPoints = properties.GetActiveUdpListeners(); portArray.AddRange(from n in endPoints where n.Port >= startingPort select n.Port); portArray.Sort(); for (var i = startingPort; i < UInt16.MaxValue; i++) if (!portArray.Contains(i)) return i; return 0; }
это решение сравнимо с принятым ответом TheSeeker. Хотя я думаю, что это более читабельно:
using System; using System.Net; using System.Net.Sockets; private static readonly IPEndPoint DefaultLoopbackEndpoint = new IPEndPoint(IPAddress.Loopback, port: 0); public static int GetAvailablePort() { using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) { socket.Bind(DefaultLoopbackEndpoint); return ((IPEndPoint)socket.LocalEndPoint).Port; } }
Если вы хотите получить свободный порт в определенном диапазоне, чтобы использовать его в качестве локального порта / конечной точки:
private int GetFreePortInRange(int PortStartIndex, int PortEndIndex) { DevUtils.LogDebugMessage(string.Format("GetFreePortInRange, PortStartIndex: {0} PortEndIndex: {1}", PortStartIndex, PortEndIndex)); try { IPGlobalProperties ipGlobalProperties = IPGlobalProperties.GetIPGlobalProperties(); IPEndPoint[] tcpEndPoints = ipGlobalProperties.GetActiveTcpListeners(); List<int> usedServerTCpPorts = tcpEndPoints.Select(p => p.Port).ToList<int>(); IPEndPoint[] udpEndPoints = ipGlobalProperties.GetActiveUdpListeners(); List<int> usedServerUdpPorts = udpEndPoints.Select(p => p.Port).ToList<int>(); TcpConnectionInformation[] tcpConnInfoArray = ipGlobalProperties.GetActiveTcpConnections(); List<int> usedPorts = tcpConnInfoArray.Where(p=> p.State != TcpState.Closed).Select(p => p.LocalEndPoint.Port).ToList<int>(); usedPorts.AddRange(usedServerTCpPorts.ToArray()); usedPorts.AddRange(usedServerUdpPorts.ToArray()); int unusedPort = 0; for (int port = PortStartIndex; port < PortEndIndex; port++) { if (!usedPorts.Contains(port)) { unusedPort = port; break; } } DevUtils.LogDebugMessage(string.Format("Local unused Port:{0}", unusedPort.ToString())); if (unusedPort == 0) { DevUtils.LogErrorMessage("Out of ports"); throw new ApplicationException("GetFreePortInRange, Out of ports"); } return unusedPort; } catch (Exception ex) { string errorMessage = ex.Message; DevUtils.LogErrorMessage(errorMessage); throw; } } private int GetLocalFreePort() { int hemoStartLocalPort = int.Parse(DBConfig.GetField("Site.Config.hemoStartLocalPort")); int hemoEndLocalPort = int.Parse(DBConfig.GetField("Site.Config.hemoEndLocalPort")); int localPort = GetFreePortInRange(hemoStartLocalPort, hemoEndLocalPort); DevUtils.LogDebugMessage(string.Format("Local Free Port:{0}", localPort.ToString())); return localPort; } public void Connect(string host, int port) { try { //Create socket Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); var localPort = GetLocalFreePort(); //Create an endpoint for the specified IP on any port IPEndPoint bindEndPoint = new IPEndPoint(IPAddress.Any, localPort); //Bind the socket to the endpoint socket.Bind(bindEndPoint); //Connect to host socket.Connect(IPAddress.Parse(host), port); socket.Dispose(); } catch (SocketException ex) { //Get the error message string errorMessage = ex.Message; DevUtils.LogErrorMessage(errorMessage); } } public void Connect2(string host, int port) { try { //Create socket var localPort = GetLocalFreePort(); //Create an endpoint for the specified IP on any port IPEndPoint bindEndPoint = new IPEndPoint(IPAddress.Any, localPort); var client = new TcpClient(bindEndPoint); //client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); //will release port when done //Connect to host client.Connect(IPAddress.Parse(host), port); client.Close(); } catch (SocketException ex) { //Get the error message string errorMessage = ex.Message; DevUtils.LogErrorMessage(errorMessage); } }
Comments