Я хочу создать новую сеть tcp://localhost:x/Service конечная точка для служебного вызова WCF с динамично присвоенным новым открытым портом TCP.
Я знаю, что TcpClient присвоит новый клиентский порт, когда я открою соединение с данным сервером.
Существует ли простой способ найти следующий открытый порт TCP в.NET?
Мне нужно фактическое число, так, чтобы я мог создать строку выше. 0 не работает, так как я должен передать ту строку другому процессу, так, чтобы я мог перезвонить на том новом канале.
Вот то, что я искал:
static int FreeTcpPort()
{
TcpListener l = new TcpListener(IPAddress.Loopback, 0);
l.Start();
int port = ((IPEndPoint)l.LocalEndpoint).Port;
l.Stop();
return port;
}
Используйте номер порта 0. Стек TCP выделит следующий свободный.
Сначала откройте порт, затем дайте правильный номер порта другому процессу.
Иначе все еще возможно, что некоторый другой процесс открывает порт сначала, и у Вас все еще есть различный.
Вот более сокращенный способ реализовать это, если Вы хотите найти следующий доступный порт 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;
}
Я нашел следующий код от Селен. Пространство имен WebDriver DLL
: OpenQA.Selenium. Внутренний
Класс : 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;
}