【问题标题】:Is there a way to specify which NetworkInterface .net will use?有没有办法指定将使用哪个 NetworkInterface .net?
【发布时间】:2018-03-30 18:19:59
【问题描述】:

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

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

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

我注意到可以通过 IP4 属性高级 TCP/IP 设置手动更改的称为“接口度量”的东西。每次都会使用编号较小的接口吗?有没有办法以编程方式更改此值?

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

【问题讨论】:

  • 我很好奇你为什么要这样设置?测试有线时只需禁用无线,反之亦然。确实,尽管我不确定为什么除非您安装了某种桥接适配器,否则为什么您将为两个网络接口使用一个 IP,此时它应该对客户端应用程序透明,以了解正在使用哪个。 ..
  • 用于自动化测试。我需要让它在没有用户干预的情况下运行两种类型的测试。我希望它能够在不丢失连接的情况下在适配器之间来回切换几天自行运行。这不是正常用法,因此测试将同时运行两个连接。
  • 为了清楚起见,您问的是如何强制 传出 流量使用 NIC1 或 NIC2 - 您不是在谈论 传入 流量吗?
  • 只是传出的流量,我不关心传入的流量

标签: c# .net httpclient network-interface


【解决方案1】:

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

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

1) 使用 P/Invoke 用 C# 代码更新路由表(参见here for a good example,但基本上你是在调用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

【讨论】:

    【解决方案2】:

    您可以使用库 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;
                            }
                        }
                    }
                }
    

    【讨论】:

      【解决方案3】:

      最好的方法是使用 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/

      【讨论】:

        【解决方案4】:

        我最终通过将有线 NIC 上的 Interface Metric 设置为低于 Wifi NIC 上的 Interface Metric 来解决这个问题。通过这种方式,我能够简单地禁用和启用有线 NIC,这将有效地更改在测试期间随时使用的 NIC。要禁用 NIC,我使用带有以下代码的 netsh.exe 命令。 “命令”是“启用”还是“禁用”,具体取决于我是打开还是关闭它:

                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();
        

        【讨论】:

          猜你喜欢
          • 2014-11-14
          • 2013-07-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-10-05
          • 1970-01-01
          相关资源
          最近更新 更多