From 0e2d3b63b70b94dc51e91182e82200b0f0949b05 Mon Sep 17 00:00:00 2001 From: ChsBuffer <33744752+chsbuffer@users.noreply.github.com> Date: Thu, 6 Aug 2020 04:19:15 +0800 Subject: [PATCH] =?UTF-8?q?=E7=AB=AF=E5=8F=A3=E5=8F=AF=E7=94=A8=E6=80=A7?= =?UTF-8?q?=E6=A3=80=E6=9F=A5=E6=A3=80=E6=9F=A5=E6=98=AF=E5=90=A6=E6=98=AF?= =?UTF-8?q?=E4=BF=9D=E7=95=99=E7=AB=AF=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Netch/Utils/PortHelper.cs | 99 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 95 insertions(+), 4 deletions(-) diff --git a/Netch/Utils/PortHelper.cs b/Netch/Utils/PortHelper.cs index 3b5f2ee9..f787b2fd 100644 --- a/Netch/Utils/PortHelper.cs +++ b/Netch/Utils/PortHelper.cs @@ -1,4 +1,7 @@ -using System.Linq; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; using System.Net.NetworkInformation; using Netch.Controllers; @@ -6,6 +9,89 @@ namespace Netch.Utils { public static class PortHelper { + private static readonly List TCPExcludedRanges = new List(); + private static readonly List UDPExcludedRanges = new List(); + + static PortHelper() + { + try + { + GetExcludedPortRange(PortType.TCP, ref TCPExcludedRanges); + GetExcludedPortRange(PortType.UDP, ref UDPExcludedRanges); + } + catch (Exception e) + { + Logging.Error("获取保留端口失败: " + e); + } + } + + private static void GetExcludedPortRange(PortType portType, ref List targetList) + { + var lines = new List(); + var process = new Process + { + StartInfo = new ProcessStartInfo + { + FileName = "netsh", + Arguments = $" int ipv4 show excludedportrange {portType}", + RedirectStandardOutput = true, + UseShellExecute = false, + CreateNoWindow = true + } + }; + process.OutputDataReceived += (s, e) => + { + if (e.Data != null) lines.Add(e.Data); + }; + process.Start(); + process.BeginOutputReadLine(); + process.WaitForExit(); + + var splitLine = false; + foreach (var line in lines) + { + if (!splitLine) + { + if (line.StartsWith("-")) + { + splitLine = true; + } + } + else + { + if (line == string.Empty) + break; + + var value = line.Trim().Split(' ').Where(s => s != string.Empty); + + var port = 0; + var _ = (from s1 in value + where int.TryParse(s1, out port) + select port).ToArray(); + + targetList.Add(_); + } + } + } + + /// + /// 检查端口是否是保留端口 + /// + /// 端口 + /// 端口类型 + /// 是否是保留端口 + /// + private static bool IsPortExcluded(int port, PortType type) + { + return type switch + { + PortType.TCP => TCPExcludedRanges.Any(range => range[0] <= port && port <= range[1]), + PortType.UDP => UDPExcludedRanges.Any(range => range[0] <= port && port <= range[1]), + PortType.Both => IsPortExcluded(port, PortType.TCP) || IsPortExcluded(port, PortType.UDP), + _ => throw new ArgumentOutOfRangeException(nameof(type), type, null) + }; + } + /// /// 指定类型的端口是否已经被使用了 /// @@ -15,10 +101,15 @@ namespace Netch.Utils public static bool PortInUse(int port, PortType type = PortType.Both) { var netInfo = IPGlobalProperties.GetIPGlobalProperties(); - var tcpResult = type != PortType.UDP && netInfo.GetActiveTcpListeners().Any(ipEndPoint => !MainController.UsingPorts.Contains(ipEndPoint.Port) && ipEndPoint.Port == port); - var udpResult = type != PortType.TCP && netInfo.GetActiveUdpListeners().Any(ipEndPoint => !MainController.UsingPorts.Contains(ipEndPoint.Port) && ipEndPoint.Port == port); + var isTcpUsed = type != PortType.UDP && + (IsPortExcluded(port, PortType.TCP) || + netInfo.GetActiveTcpListeners().Any(ipEndPoint => ipEndPoint.Port == port)); + var isUdpUsed = type != PortType.TCP && + (IsPortExcluded(port, PortType.UDP) || + netInfo.GetActiveUdpListeners().Any(ipEndPoint => ipEndPoint.Port == port)); + var isPortExcluded = !MainController.UsingPorts.Contains(port); - return tcpResult || udpResult; + return isPortExcluded && (isTcpUsed || isUdpUsed); } }