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

C# 在C中确定WiFi的当前链路速度#,c#,wifi,wireless,C#,Wifi,Wireless,我正在写一个程序,它做一件事,找出当前的无线连接速度,并报告给用户实时。我遇到的问题是,它似乎无法找到当前的链路速度,只能找到设备的最大链路速度(300 Mbps)。我写这篇文章的原因是我遇到了一个问题,链路速度会周期性地急剧下降(降至1-2Mbps),我希望能够看到这种情况何时发生。有了这段代码,它只会给我适配器支持的最大速度,而不是连接的当前链接速度 private void update(object state) { System.Net.NetworkInformation.

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

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

在主要方法中。

考虑到我花了整整一天的时间才找到解决这个问题的方法,我想我至少应该向StackOverflow展示我在这个问题上遇到了什么,做了什么和没有做什么,以备将来参考

tl;dr:滚动至代码部分

我发现了什么 好的ol控制面板 如果你正在寻找一种非常简单的方法来做这件事,你可以简单地去打开控制面板。根据您所使用的Windows版本(在我的情况下,我使用的是Windows 8),该页面的路径是控制面板>>网络和Internet>>网络和共享中心,然后您可以单击“连接:”旁边的链接,该链接将为您提供一个如下所示的窗口。
当前链路速度以红色突出显示,在我的情况下为36.0 Mbps。当然,如果您打算将某些代码与实际值集成,那么这可能无法满足您最初的问题

WMI 通过谷歌搜索和诸如此类的混合,我想我可能在这方面有所发现

长话短说,好吧,WMI没有我们想要的东西

简而言之,WMI是一个巨大的对象数据库(即 也可以通过SQL查询),它允许您查询有关 Windows计算机,如进程、磁盘等。在WMI中,所有内容都是 由具有一系列实例的类表示,每个实例具有一组 属性。
无论如何,允许您在计算机上查看所有这些内容

我(据推测)在MSDN上发现了两个类,它们可能有链接速度的信息,但从WMI资源管理器中,没有任何有用的信息

第一个类,甚至没有出现在我的机器上的WMI资源管理器中

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

从名单上划掉WMI

Win32 P/Invoke 当然,所有问题的解决方案都是使用magic调用非托管Win32 API

这是用于解决问题的路径

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

调用将返回实际结构

现在,实际的C#p/调用代码。幸运的是,对于我添加的这个函数。这是所有必要的

代码 最后,这里是用新的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);
    }
}
代码:

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
类。因为它相当大,你可以在这里找到它的更新,以防发生故障

底线 Windows有很多API,这些API有些不完整(WMI),可能有一些(.Net),或者很难使用(Win32)


唉,这太多了,我希望它能有所帮助。

我遇到了同样的问题,需要获得当前协商的windows wifi链接速度。 感谢@Jaxrtech的WMI方法,这真的很有效。 正确的类是CIM_NetworkAdapter(我使用的是windows7),并查询速度列以获取当前速度。 虽然wifi当前协商速度在变化,但这种速度也在变化。我测试过了,这个匹配正常

select Description , DeviceID, Speed from CIM_NetworkAdapter
获取:


我不是想确定互联网速度,而是想确定802.11n连接的链路速度。这些数字可能是28、56、72、96、116、124、130、148、156、162、192、216、232、240、270或300。这是我甚至不用连接互联网就能获得的信息。这是理论上可以通过网络发送的最大带宽,而不是实际的最大带宽。非常感谢。我已经有了控制面板的方法,还有另一种方法,是Windows8特有的,但是没有一种方法适合我的需要。你的代码正是我想要的,非常感谢。有人在uwp上测试过这个吗?