有没有办法指定 .net 将使用哪个 NetworkInterface?

Is there a way to specify which NetworkInterface .net will use?

我想 运行 使用 Wifi 和 LAN 连接在设备上进行一系列测试。我有两张网卡,一张是WiFi,一张是有线。该设备具有可通过两个网络接口访问的单个 IP 地址。有没有办法保证我的机器使用特定的网络接口,以便我可以 运行 通过有线连接进行所有测试,然后 运行 通过 Wifi 连接进行所有测试?

请记住,两个连接共享同一个子网,因此任何一个都将成功连接到设备。我只想能够来回切换并指定我在任何给定时间使用的连接。

我正在使用 C# 在 .net 上使用 HttpClient。有没有办法强制 HttpClient 使用特定的网络接口?它似乎会根据 IP 地址自动选择一个,但在这种情况下,有 2 个网络接口可以工作。我需要能够以编程方式来回切换到 运行 我的自动化测试。

我注意到一个叫做 'Interface Metric' 的东西,可以通过 IP4 属性高级 TCP/IP 设置手动更改。每次都会使用编号较小的接口吗?有没有办法以编程方式更改此值?

更多说明:我没有直接跳到禁用 WiFi NIC 或有线 NIC 来回的原因是当您禁用 WiFi NIC 时,您断开了它所连接的设备,它不会自动启用它时重新连接。 (即使你说 'connect automatically' 它在重新启用时也不会连接)。但是,我找到了一个快速的解决方案。将有线 NIC 上的接口指标设置为低于 WiFi NIC 上的接口指标。然后,只需启用和禁用有线 NIC。禁用时,系统将使用 WiFi NIC。启用后,系统将使用有线 NIC,因为它的接口指标设置得较低。现在,我只需要弄清楚如何以编程方式 enable/disable 有线 NIC...

一种方法是更新您的路由 table 以强制特定 IP 的流量到特定的 NIC。路由 table 用于决定将流量发送到哪个 NIC。

您可以通过几种方式做到这一点:

1) 使用P/Invoke用C#代码更新路由table(参见here for a good example, but basically you are calling CreateIpForwardEntry)。

2) 使用Process.Start调用route.exe,例如

route.exe ADD destination_network MASK subnet_mask  gateway_ip metric_cost

route.exe CHANGE destination_network MASK subnet_mask  gateway_ip metric_cost

最好的方法是使用 WinSock 绑定:TCP/IP connection on a specific interface

但是一旦你有两个网卡的单一 IP,那么:

从 PowerShell 禁用 NIC:https://docs.microsoft.com/en-us/powershell/module/netadapter/disable-netadapter?view=win10-ps

从 c# 调用 PowerShell:https://blogs.msdn.microsoft.com/kebab/2014/04/28/executing-powershell-scripts-from-c/

我最终通过将有线 NIC 上的接口指标设置为低于 Wifi NIC 上的接口指标来解决此问题。通过这种方式,我能够简单地禁用和启用有线 NIC,这将在测试期间随时有效地更改正在使用的 NIC。要禁用 NIC,我使用带有以下代码的 netsh.exe 命令。 'command' 是 'enable' 或 'disable' 取决于我是打开还是关闭它:

        System.Diagnostics.Process p = new System.Diagnostics.Process
        {
            StartInfo =
            {
                FileName = "netsh.exe",
                Arguments = $"interface set interface \"{nicName}\" {command}",
                UseShellExecute = false,
                RedirectStandardOutput = true
            }
        };

        bool started = p.Start();

您可以使用图书馆 WlanAPI.cs

static public void Connect_to_wifi(string ssid)
            {
                WlanClient client = new WlanClient();
                foreach (WlanClient.WlanInterface wlanIface in client.Interfaces)
                {
                    // Lists all networks with WEP security
                    //Wlan.WlanAvailableNetwork[] networks = wlanIface.GetAvailableNetworkList(0);
                    //foreach (Wlan.WlanAvailableNetwork network in networks)
                    //{
                    //    if (network.dot11DefaultCipherAlgorithm == Wlan.Dot11CipherAlgorithm.WEP)
                    //    {
                    //        Console.WriteLine("Found WEP network with SSID {0}.", network.profileName);
                    //    }
                    //}
    
                    // Retrieves XML configurations of existing profiles.
                    // This can assist you in constructing your own XML configuration
                    // (that is, it will give you an example to follow).
                    foreach (Wlan.WlanProfileInfo profileInfo in wlanIface.GetProfiles())
                    {
                        if (profileInfo.profileName == ssid)
                        {
                            wlanIface.SetProfile(Wlan.WlanProfileFlags.AllUser, wlanIface.GetProfileXml(profileInfo.profileName), true);
                            wlanIface.Connect(Wlan.WlanConnectionMode.Profile, Wlan.Dot11BssType.Any, profileInfo.profileName);
                            break;
                        }
                    }
                }
            }