136 lines
4.4 KiB
C#
136 lines
4.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Net;
|
|
using System.Net.NetworkInformation;
|
|
using System.Threading;
|
|
|
|
namespace Ultron.Proxy.Utils
|
|
{
|
|
public class NetworkUtil
|
|
{
|
|
private const string PortReleaseGuid = "C086DE94-2C45-4247-81E2-2E5248F5A769";
|
|
|
|
private static HashSet<int> _usedPorts = new HashSet<int>();
|
|
|
|
/// <summary>
|
|
/// 查找一个端口
|
|
/// </summary>
|
|
/// <param name="startPort"></param>
|
|
/// <returns></returns>
|
|
public static int FindOneAvailableTCPPort(int startPort)
|
|
{
|
|
return NetworkUtil.FindAvailableTCPPorts(startPort, 1)[0];
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check if startPort is available, incrementing and
|
|
/// checking again if it's in use until a free port is found
|
|
/// </summary>
|
|
/// <param name="startPort">The first port to check</param>
|
|
/// <returns>The first available port</returns>
|
|
public static int[] FindAvailableTCPPorts(int startPort, int PortCount)
|
|
{
|
|
int[] arrangedPorts = new int[PortCount];
|
|
int port = startPort;
|
|
bool isAvailable = true;
|
|
|
|
var mutex = new Mutex(false,
|
|
PortReleaseGuid
|
|
/*string.Concat("./Global/", PortReleaseGuid)*/);
|
|
mutex.WaitOne();
|
|
try
|
|
{
|
|
for (int i = 0; i < PortCount; i++)
|
|
{
|
|
IPGlobalProperties ipGlobalProperties =
|
|
IPGlobalProperties.GetIPGlobalProperties();
|
|
IPEndPoint[] endPoints =
|
|
ipGlobalProperties.GetActiveTcpListeners();
|
|
|
|
do
|
|
{
|
|
if (!isAvailable)
|
|
{
|
|
port++;
|
|
isAvailable = true;
|
|
}
|
|
if (_usedPorts.Contains(port))
|
|
{
|
|
isAvailable = false;
|
|
continue;
|
|
}
|
|
foreach (IPEndPoint endPoint in endPoints)
|
|
{
|
|
if (endPoint.Port != port) continue;
|
|
isAvailable = false;
|
|
break;
|
|
}
|
|
|
|
} while (!isAvailable && port < IPEndPoint.MaxPort);
|
|
|
|
if (!isAvailable)
|
|
throw new ApplicationException("Not able to find a free TCP port.");
|
|
arrangedPorts[i] = port;
|
|
_usedPorts.Add(port);
|
|
}
|
|
return arrangedPorts;
|
|
}
|
|
finally
|
|
{
|
|
mutex.ReleaseMutex();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check if startPort is available, incrementing and
|
|
/// checking again if it's in use until a free port is found
|
|
/// </summary>
|
|
/// <param name="startPort">The first port to check</param>
|
|
/// <returns>The first available port</returns>
|
|
public static int FindNextAvailableUDPPort(int startPort)
|
|
{
|
|
int port = startPort;
|
|
bool isAvailable = true;
|
|
|
|
var mutex = new Mutex(false,
|
|
string.Concat("Global/", PortReleaseGuid));
|
|
mutex.WaitOne();
|
|
try
|
|
{
|
|
IPGlobalProperties ipGlobalProperties =
|
|
IPGlobalProperties.GetIPGlobalProperties();
|
|
IPEndPoint[] endPoints =
|
|
ipGlobalProperties.GetActiveUdpListeners();
|
|
|
|
do
|
|
{
|
|
if (!isAvailable)
|
|
{
|
|
port++;
|
|
isAvailable = true;
|
|
}
|
|
|
|
foreach (IPEndPoint endPoint in endPoints)
|
|
{
|
|
if (endPoint.Port != port)
|
|
continue;
|
|
isAvailable = false;
|
|
break;
|
|
}
|
|
|
|
} while (!isAvailable && port < IPEndPoint.MaxPort);
|
|
|
|
if (!isAvailable)
|
|
throw new ApplicationException("Not able to find a free TCP port.");
|
|
|
|
return port;
|
|
}
|
|
finally
|
|
{
|
|
mutex.ReleaseMutex();
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|