2023-04-07 (金)
[C#] 使用中のポートを取得し、空きポートを探す方法
TCP, UDP の使用中のポートを全て取得する方法です。
アプリから動的に Web サーバーを立ち上げる際に、空きポートを指定する必要があったため、指定したポート番号以降の最初の空きポートを取得方法もメモします。
環境
- .NET 7.0.202
- C# 11.0
- Visual Studio 2022 Version 17.5.3
- Windows 10 Pro 64bit 22H2 19045.2728
実装
使用中のポートを取得する
using System.Collections.Generic;
using System.Net.NetworkInformation;
static IEnumerable<int> EnumerateActivePorts()
{
    var ipGlobalProperties = IPGlobalProperties.GetIPGlobalProperties();
    foreach (var connection in ipGlobalProperties.GetActiveTcpConnections())
    {
        yield return connection.LocalEndPoint.Port;
    }
    foreach (var tcpListener in ipGlobalProperties.GetActiveTcpListeners())
    {
        yield return tcpListener.Port;
    }
    foreach (var udpListener in ipGlobalProperties.GetActiveUdpListeners())
    {
        yield return udpListener.Port;
    }
}
指定したポート番号以降の最初の空きポートを取得する
using System.Collections.Generic;
using System.Linq;
using System.Net.NetworkInformation;
static int GetAvailablePort(int startPort)
{
    var ipGlobalProperties = IPGlobalProperties.GetIPGlobalProperties();
    var connections = ipGlobalProperties.GetActiveTcpConnections().Select(x => x.LocalEndPoint);
    var tcpListeners = ipGlobalProperties.GetActiveTcpListeners();
    var udpListeners = ipGlobalProperties.GetActiveUdpListeners();
    var activePorts = new HashSet<int>(connections
        .Concat(tcpListeners)
        .Concat(udpListeners)
        .Where(x => x.Port >= startPort)
        .Select(x => x.Port));
    for (var port = startPort; port <= 65535; port++)
    {
        if (!activePorts.Contains(port))
            return port;
    }
    return -1;
}
空きポートを自動取得する
using System.Net;
using System.Net.Sockets;
static int FindFreePort()
{
    using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    socket.Bind(new IPEndPoint(IPAddress.Any, 0));
    var endPoint = (IPEndPoint?)socket.LocalEndPoint;
    return endPoint?.Port ?? -1;
}
注意
UWP や Azure 上では、以下のメソッドで例外が発生するようです。
IPGlobalProperties.GetActiveTcpConnections();
IPGlobalProperties.GetActiveTcpListeners();
IPGlobalProperties.GetActiveUdpListeners();
- “Access is denied” when calling IPGlobalProperties.GetActiveUdpListeners on UWP · Issue #24369 · dotnet/runtime
- c# - Find the next TCP port in .NET - Stack Overflow
感謝
関連記事
新着記事