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

时间:2008-09-26 06:33:51

标签: c# .net wcf networking tcp

我想为WCF服务调用创建一个新的net.tcp:// localhost:x / Service端点,并动态分配新的开放TCP端口。

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

有没有一种简单的方法可以在.NET中找到下一个打开的TCP端口?

我需要实际的数字,以便我可以在上面构建字符串。 0不起作用,因为我需要将该字符串传递给另一个进程,以便我可以回调该新频道。

7 个答案:

答案 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;
}