在.Net中查找下一个TCP端口

我想为一个WCF服务调用创build一个新的net.tcp:// localhost:x / Service端点,并带有一个dynamic分配的新的打开tcp端口。

我知道,当我打开一个连接到给定的服务器时,TcpClient将分配一个新的客户端端口。

有没有一种简单的方法来find下一个开放的TCP端口在.Net?

我需要实际的编号,以便我可以构build上面的string,0不起作用,因为我需要将该string传递给另一个进程,以便我可以在该新通道上callback。

这是我正在寻找的东西:

static int FreeTcpPort() { TcpListener l = new TcpListener(IPAddress.Loopback, 0); l.Start(); int port = ((IPEndPoint)l.LocalEndpoint).Port; l.Stop(); return port; } 

使用端口号0. TCP堆栈将分配下一个空闲的。

首先打开端口,然后将正确的端口号给另一个进程。

否则,其他进程仍然有可能首先打开端口,而您仍然有一个不同的进程。

如果你想获得一个特定范围内的空闲端口,以便将其用作本地端口/端点:

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

如果你只是想给一个起始端口,让它返回给你下一个可用的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; }