В качестве альтернативы ответа TempoClick , мы можем использовать метод IPGlobalProperties.GetActiveTcpListeners()
, чтобы проверить, доступен ли порт - не пытаясь открыть его заранее.GetActiveTcpListeners()
возвращает всех активных прослушивателей TCP в системе, поэтому мы можем использовать его, чтобы определить, свободен порт или нет.
public bool IsFree(int port)
{
IPGlobalProperties properties = IPGlobalProperties.GetIPGlobalProperties();
IPEndPoint[] listeners = properties.GetActiveTcpListeners();
int[] openPorts = listeners.Select(item => item.Port).ToArray<int>();
return openPorts.All(openPort => openPort != port);
}
Обратите внимание, что GetActiveTcpListeners()
не возвращает прослушиваемые конечные точки UDP, но мы можем получить их с помощью GetActiveUdpListeners()
.
Итак, вы можете начать с порта по умолчанию (или выбрать случайное значение) и продолжать увеличивать его, пока не найдете свободный порт с помощью метода IsFree
.
int NextFreePort(int port = 0)
{
port = (port > 0) ? port : new Random().Next(1, 65535);
while (!IsFree(port))
{
port += 1;
}
return port;
}
Простой тест:
using System;
using System.Net;
using System.Net.Sockets;
using System.Net.NetworkInformation;
using System.Linq;
class Test
{
static void Main(string[] args)
{
int port = 1000;
Console.WriteLine(IsFree(port));
TcpListener server = new TcpListener(IPAddress.Parse("127.0.0.1"), port);
server.Start();
Console.WriteLine(IsFree(port));
Console.WriteLine(NextFreePort(port));
}
static bool IsFree(int port)
{
IPGlobalProperties properties = IPGlobalProperties.GetIPGlobalProperties();
IPEndPoint[] listeners = properties.GetActiveTcpListeners();
int[] openPorts = listeners.Select(item => item.Port).ToArray<int>();
return openPorts.All(openPort => openPort != port);
}
static int NextFreePort(int port = 0) {
port = (port > 0) ? port : new Random().Next(1, 65535);
while (!IsFree(port)) {
port += 1;
}
return port;
}
}
Другой подход заключается в использовании нулевого порта.В этом случае система выберет произвольно свободный порт из диапазона динамических портов.Мы можем получить номер этого порта из свойства LocalEndpoint
.
TcpListener server = new TcpListener(IPAddress.Loopback, 0);
server.Start();
int port = ((IPEndPoint)server.LocalEndpoint).Port;
Console.WriteLine(port);