我想为WCF服务调用创建一个新的net.tcp:// localhost:x / Service端点,并动态分配新的开放TCP端口。
我知道当我打开与给定服务器的连接时,TcpClient将分配一个新的客户端端口。
有没有一种简单的方法可以在.NET中找到下一个打开的TCP端口?
我需要实际的数字,以便我可以在上面构建字符串。 0不起作用,因为我需要将该字符串传递给另一个进程,以便我可以回调该新频道。
答案 0 :(得分:115)
以下是我要找的内容:
static int FreeTcpPort()
{
TcpListener l = new TcpListener(IPAddress.Loopback, 0);
l.Start();
int port = ((IPEndPoint)l.LocalEndpoint).Port;
l.Stop();
return port;
}
答案 1 :(得分:18)
使用端口号0. TCP堆栈将分配下一个免费的。
答案 2 :(得分:9)
首先打开端口,然后将正确的端口号提供给另一个进程。
否则,某些其他进程仍然可能首先打开该端口,但您仍然有另一个进程。
答案 3 :(得分:7)
这是一个可与TheSeeker接受的答案相媲美的解决方案。虽然我觉得它更具可读性:
sed
答案 4 :(得分:4)
如果您只想提供一个起始端口,并让它返回给您可用的下一个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;
}
答案 5 :(得分:3)
我从 Selenium.WebDriver DLL
找到了以下代码命名空间:OpenQA.Selenium.Internal
类:PortUtility
public static int FindFreePort()
{
int port = 0;
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
IPEndPoint localEP = new IPEndPoint(IPAddress.Any, 0);
socket.Bind(localEP);
localEP = (IPEndPoint)socket.LocalEndPoint;
port = localEP.Port;
}
finally
{
socket.Close();
}
return port;
}
答案 6 :(得分:0)
如果要在给定范围内找到下一个可用的TCP端口,则这是一种简化的实现方式:
private int GetNextUnusedPort(int min, int max)
{
if (max < min)
throw new ArgumentException("Max cannot be less than min.");
var ipProperties = IPGlobalProperties.GetIPGlobalProperties();
var usedPorts =
ipProperties.GetActiveTcpConnections()
.Where(connection => connection.State != TcpState.Closed)
.Select(connection => connection.LocalEndPoint)
.Concat(ipProperties.GetActiveTcpListeners())
.Concat(ipProperties.GetActiveUdpListeners())
.Select(endpoint => endpoint.Port)
.ToArray();
var firstUnused =
Enumerable.Range(min, max - min)
.Where(port => !usedPorts.Contains(port))
.Select(port => new int?(port))
.FirstOrDefault();
if (!firstUnused.HasValue)
throw new Exception($"All local TCP ports between {min} and {max} are currently in use.");
return firstUnused.Value;
}