Get random free opened port for tests
As an alternative to TempoClick's answer, we can use the IPGlobalProperties.GetActiveTcpListeners()
method to test if a port is available - without trying to open it in advance. GetActiveTcpListeners()
returns all active TCP listeners on the system, and so we can use it to determine if a port is free or not.
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);
}
Note that GetActiveTcpListeners()
doesn't return listening UDP endpoints, but we can get them with GetActiveUdpListeners()
.
So, you can start with the default port (or select a random value) and keep incrementing until you find a free port with the IsFree
method.
int NextFreePort(int port = 0)
{
port = (port > 0) ? port : new Random().Next(1, 65535);
while (!IsFree(port))
{
port += 1;
}
return port;
}
A simple test:
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;
}
}
A different approach is to use port zero. In this case, the system will select a random free port from the dynamic port range. We can get the number ot this port from the LocalEndpoint
property.
TcpListener server = new TcpListener(IPAddress.Loopback, 0);
server.Start();
int port = ((IPEndPoint)server.LocalEndpoint).Port;
Console.WriteLine(port);
To get a free port
static int FreePort()
{
TcpListener l = new TcpListener(IPAddress.Loopback, 0);
l.Start();
int port = ((IPEndPoint)l.LocalEndpoint).Port;
l.Stop();
return port;
}