在C#中确定WiFi的当前链接速度

时间:2013-07-07 21:26:21

标签: c# wifi wireless

我正在编写一个程序做一件事,它找出了wifi连接的当前链接速度并实时报告给用户。我遇到的问题是它似乎无法找出当前的链接速度,只能找到设备的最大链接速度(300 Mbps)。我写这个的原因是我有一个问题,周期性的链接速度将急剧下降(低至1-2 Mbps),我希望能够看到何时发生。使用此代码,它将简单地为我提供适配器支持的最大速度,而不是连接的当前链接速度。

private void update(object state)
{

    System.Net.NetworkInformation.NetworkInterface[] nics = null;
    nics = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
    long speed = 0;
    string adapter = "";
    foreach (System.Net.NetworkInformation.NetworkInterface net in nics)
    {
        if (net.Name.Contains("Wireless") || net.Name.Contains("WiFi") || net.Name.Contains("802.11") || net.Name.Contains("Wi-Fi"))
        {
            speed = net.Speed;
            adapter = net.Name;
            break;
        }
    }
    string temp;
    if (speed == 0)
    {
        temp = "There is currently no Wi-Fi connection";
    }
    else
    {
        temp = "Current Wi-Fi Speed: " + (speed / 1000000) + "Mbps on " + adapter;
    }
    if (label1.InvokeRequired)
    {
        SetTextCallback d = new SetTextCallback(update);
        label1.Invoke(d, new object[] { temp });
    }
    else
    {
        label1.Text = temp;
    }
}

通过调用

运行
System.Threading.Timer ticker = new System.Threading.Timer(update, label1, 0, 1000);

在主要方法中。

3 个答案:

答案 0 :(得分:13)

考虑到我花了整整一天的时间才找到解决方案的问题,我想我至少会展示StackOverflow,以便将来参考我所遇到的以及做了什么和做了为这个问题工作。

tl; dr: 滚动至代码部分

我找到了什么

Good ol'控制面板

如果您正在寻找非常简单的方法,您可以直接打开Contol Panel。根据您所使用的Windows版本(在我的情况下,我在Windows 8上),该页面的路径是控制面板>>网络和互联网>>网络和共享中心,然后您可以点击“Connections:”旁边的链接,它将为您提供一个如下所示的窗口。Wi-Fi Info Window 当前链路速度以红色突出显示,在我的情况下为36.0 Mbps。当然,如果您打算将某些代码与实际值集成,这可能无法满足您的原始问题。

WMI

混合使用谷歌搜索和诸如此类的东西,我想我可能在Windows Management Instrumentation找到了一些东西。

长话短说,AFAIK,WMI 拥有我们正在寻找的东西。

  简而言之,

WMI 是一个巨大的对象数据库(那个   也可以通过SQL查询,允许您查询有关的信息   Windows机器,如进程,磁盘等。在WMI中,一切都是   由表示,其中包含一系列实例   属性
  无论如何,WMI Explorer允许您在计算机上查看所有这些内容。

我(据说)在MSDN上发现了两个可能具有链接速度信息的类但是从WMI资源管理器中没有任何用处。

第一堂课MSFT_NetAdapter甚至没有出现在我的机器上的WMI资源管理器中。

第二个类Win32_NetworkAdapter出现在WMI资源管理器中,但Speed属性仍然不正确。同一网络适配器显示的值为168000000或168 Mbps,这是不正确的。虽然我发现这很奇怪,因为已经有MaxSpeed,但它是空白的。

从列表中删除WMI。

Win32 P / Invoke

是的,当然 ,所有内容的解决方案总是使用P/Invoke magic来调用非托管的Win32 API。

这是解决问题的途径

幸运的是,IP_ADAPTER_ADDRESSES structure解决了这个问题。如果您查看MSDN页面,它是一个相当大的结构,但重要的是TransmitLinkSpeed 实际上正常工作

调用GetAdaptersAddresses() function将返回实际结构。

现在,实际的C#P / Invoke代码。幸运的是,pinvoke.net already had interop对于我添加的这个功能。这就是必要的。

守则

最后,这里是你的代码用新的P / Invoke黑魔法补丁。我已将它作为控制台应用程序用于演示目的:

使用语句:

using System;
using System.Threading;

<强>代码:

class Program
{
    private static void Main(string[] args)
    {
        Timer ticker = new Timer(Update, null, 0, 1000);

        // Keep the main thread from dying
        while (true)
        {
            Thread.Sleep(1000);
        }
    }

    private static void Update(object state)
    {
        ulong speed = 0;
        string adapter = "";

        string[] nameSearches = { "Wireless", "WiFi", "802.11", "Wi-Fi" };

        // The enum value of `AF_INET` will select only IPv4 adapters.
        // You can change this to `AF_INET6` for IPv6 likewise
        // And `AF_UNSPEC` for either one
        foreach (IPIntertop.IP_ADAPTER_ADDRESSES net in IPIntertop.GetIPAdapters(IPIntertop.FAMILY.AF_INET))
        {
            bool containsName = false;
            foreach (string name in nameSearches)
            {
                if (net.FriendlyName.Contains(name))
                {
                    containsName = true;
                }
            }
            if (!containsName) continue;

            speed = net.TrasmitLinkSpeed;
            adapter = net.FriendlyName;
            break;
        }

        string temp;
        if (speed == 0)
        {
            temp = "There is currently no Wi-Fi connection";
        }
        else
        {
            temp = string.Format("Current Wi-Fi Speed: {0} Mbps on {1}", (speed / 1000000.0), adapter);
        }

        Console.WriteLine(temp);
    }
}

然后您将要查找我更新的实际IPIntertop类。由于它非常大,您可以在pinvoke.netPasteBin上更新,以防万一发生故障。

底线

Windows有一些很多的API,它们有些破碎(WMI),可能有一些"leaky abstractions"(。Net),或者可能很难使用(Win32)。

叹息,这很多,我希望它有所帮助。

答案 1 :(得分:1)

我遇到了同样的问题,需要获得当前协商的Windows wifi链接速度。 并且感谢@ Jaxrtech的WMI方法,这确实有效。 正确的类是CIM_NetworkAdapter(我正在使用windows7),并查询速度列以获取当前速度。 当wifi协议速度正在变化时,这个速度也在变化。我测试了它,这匹配好了。

select Description , DeviceID, Speed from CIM_NetworkAdapter

得到:

D-Link DWA-140 RangeBooster N USB Adapter    17    285000000

答案 2 :(得分:0)

既然这里还没有人提到它:为什么不使用 https://docs.microsoft.com/en-us/dotnet/api/system.net.networkinformation.networkinterface.speed?view=net-5.0#System_Net_NetworkInformation_NetworkInterface_Speed

这是,如果此站点上的表格自 .NET Framework 2.0 起包含正确,并且似乎包含在所有其他版本的 .net 中,包括 .net core。