using System.Collections.Generic; using System.Linq; using System.Net.NetworkInformation; using System.Net.Sockets; using NetTool.Client.Models; namespace NetTool.Client.Services; public sealed class NetworkAdapterService { public IReadOnlyList GetAdapters() { return NetworkInterface .GetAllNetworkInterfaces() .Select(BuildAdapterInfo) .OrderByDescending(adapter => adapter.RecommendationScore) .ThenBy(adapter => adapter.Name) .ToList(); } public AdapterInfo? GetRecommendedAdapter(IReadOnlyList adapters) { return adapters .OrderByDescending(adapter => adapter.RecommendationScore) .ThenBy(adapter => adapter.Name) .FirstOrDefault(); } private static AdapterInfo BuildAdapterInfo(NetworkInterface adapter) { var ipv4Address = adapter .GetIPProperties() .UnicastAddresses .FirstOrDefault(address => address.Address.AddressFamily == AddressFamily.InterNetwork) ?.Address .ToString() ?? string.Empty; var score = GetRecommendationScore(adapter, ipv4Address); var (label, reason) = GetRecommendation(score, adapter, ipv4Address); return AdapterInfo.FromNetworkInterface(adapter, ipv4Address, score, label, reason); } private static int GetRecommendationScore(NetworkInterface adapter, string ipv4Address) { var score = 0; var description = adapter.Description; var isVirtual = IsVirtualAdapter(description); if (adapter.NetworkInterfaceType is NetworkInterfaceType.Ethernet or NetworkInterfaceType.GigabitEthernet) { score += 50; } if (adapter.OperationalStatus == OperationalStatus.Up) { score += 40; } if (ipv4Address.StartsWith("169.254.", System.StringComparison.Ordinal)) { score += 30; } if (!isVirtual) { score += 20; } if (description.Contains("Intel", System.StringComparison.OrdinalIgnoreCase) || description.Contains("Realtek", System.StringComparison.OrdinalIgnoreCase) || description.Contains("Broadcom", System.StringComparison.OrdinalIgnoreCase)) { score += 10; } if (isVirtual) { score -= 40; } return score; } private static (string Label, string Reason) GetRecommendation(int score, NetworkInterface adapter, string ipv4Address) { if (score >= 90) { if (ipv4Address.StartsWith("169.254.", System.StringComparison.Ordinal)) { return ("推荐", "已连接且当前 IPv4 为 169.254 网段,最像初始化直连网卡。"); } return ("推荐", "已检测到已连接的网卡,适合作为初始化连接口。"); } if (score >= 40) { return ("可选", "该网卡可用,但不是最优候选,请确认是否为实际直连接口。"); } return ("不建议", "该网卡更像虚拟或非直连接口,通常不建议用于设备初始化。"); } private static bool IsVirtualAdapter(string description) { return description.Contains("VMware", System.StringComparison.OrdinalIgnoreCase) || description.Contains("Virtual", System.StringComparison.OrdinalIgnoreCase) || description.Contains("Hyper-V", System.StringComparison.OrdinalIgnoreCase) || description.Contains("TAP", System.StringComparison.OrdinalIgnoreCase) || description.Contains("VPN", System.StringComparison.OrdinalIgnoreCase) || description.Contains("Loopback", System.StringComparison.OrdinalIgnoreCase); } }