我正在编写一个程序做一件事,它找出了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;
}
}
Run Code Online (Sandbox Code Playgroud)
这是通过调用运行
System.Threading.Timer ticker = new System.Threading.Timer(update, label1, 0, 1000);
Run Code Online (Sandbox Code Playgroud)
在主要方法.
Jos*_*den 14
考虑到只花了我整个整天找到什么解决方案,这是,我想我至少以供将来参考展示的StackOverflow是我碰到的,什么是,也没有对这个问题的工作.
tl; dr: 滚动到The Code部分
如果您正在寻找真正简单的方法,您可以直接打开Contol Panel.根据您所使用的Windows版本(在我的情况下,我在Windows 8上),该页面的路径是控制面板>>网络和Internet >>网络和共享中心,然后您可以单击旁边的链接"连接:"会给你一个看起来像下面的窗口.
当前链路速度以红色突出显示,在我的情况下为36.0 Mbps.当然,如果您打算将某些代码与实际值集成,这可能无法满足您的原始问题.
混合了谷歌搜索和诸如此类的东西,我想我可能在Windows Management Instrumentation中找到了一些东西.
长话短说,据我所知,WMI 也不会有什么我们要寻找的.
简而言之,WMI是一个巨大的对象数据库(也可以通过SQL查询),它允许您查询有关Windows机器的信息,如进程,磁盘等.在WMI中,所有内容都由一系列的类表示.每个实例都有一组 属性.
无论如何,WMI Explorer允许您在计算机上查看所有这些内容.
我(据说)在MSDN上发现了两个类可能有关于链接速度的信息但是从WMI资源管理器中没有任何用处.
第一个类,MSFT_NetAdapter甚至没有显示在我的机器上的WMI资源管理器中.
第二个类Win32_NetworkAdapter出现在WMI资源管理器中,但Speed属性仍然不正确.同一个网络适配器显示的值为168000000168 Mbps,这是不对的.虽然我发现这很奇怪,因为已经有了MaxSpeed但它是空白的.
将WMI从列表中删除.
是的,当然,解决所有问题的方法总是使用P/Invoke魔法来调用非托管的Win32 API .
这是用于解决问题的途径.
幸运的是,IP_ADAPTER_ADDRESSES结构解决了这个问题.如果你看一下MSDN页面,它是一个相当大的结构,但重要的是TransmitLinkSpeed它实际上是有效的.
调用该GetAdaptersAddresses()函数将返回实际结构.
现在,实际的C#P/Invoke代码.幸运的是,pinvoke.net已经为我已经添加的这个功能进行了互操作.这就是必要的.
最后,这里是你的代码修补了新的P/Invoke黑魔法.我已将它作为控制台应用程序用于演示目的:
使用语句:
using System;
using System.Threading;
Run Code Online (Sandbox Code Playgroud)
码:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
然后,您将要查找IPIntertop我更新的实际课程.因为它非常大,所以你可以在pinvoke.net或者这个PasteBin上找到它,以防万一有什么事情发生.
Windows有很多有点破坏的API(WMI),可能有一些"漏洞抽象"(.Net),或者可能很难使用(Win32).
叹了口气,这很多,我希望它有所帮助.
| 归档时间: |
|
| 查看次数: |
5767 次 |
| 最近记录: |