一种更优的获取网络使用率的方案(a better solution to get network utilization)
2010-01-06 23:08
429 查看
这两天一直在研究如何去获取网络利用率(usage)和网卡线路速度(link speed)的问题,找到了一个比较好的方案,写出来跟大家分享一下。
记得我在以前的一篇博文中提到过这样一个问题,有时我们添加两个虚拟网卡时,两个网卡名称是一样的,这样的结果就是我们无法根据名称去匹配指定的网卡。
通常我们获取网卡的信息有两种方式:1. WMI的win32_networkAdapter类;2. IpHlpApi框架。
而获取网络使用率的方式也有两种:1. performance monitor编程接口;2. Win32_PerfFormattedData_Tcpip_NetworkInterface类。
但是我发现这些方式都没办法解决我以上提到的问题。因为无论是从performance monitor,还是Win32_PerfFormattedData_Tcpip_NetworkInterface来获取网络利用率都是依赖于网卡名。另外,我发现在Windows Task manager里面看的网络使用率和线路速度都匹配的很正常。所以,直觉是觉得应该有一种方式可以比较好的去获取这两个值,无论网卡名是否相同。通过研究发现,其实想要获取这两个值,并且建立匹配关系可以通过WMI和IpHlpApi框架来实现。顺便说一句,我的目标是该程序能运行在win2000以后的所有系统上,所以出于兼容性的考虑,我会放弃那些只支持vista之后操作系统的方案。下面我们具体来看一下,如何用代码来实现:
为了获得WMI和IpHlpApi框架的支持,我们需要包含下面几个头文件和库:
#include <Wbemidl.h>
#include <comdef.h>
#include <Iphlpapi.h>
#pragma comment(lib , "Iphlpapi.lib")
同样为了使用智能指针,我又做了以下声明
代码
int _tmain(int argc, _TCHAR* argv[])
{
CoInitialize(NULL);
vector<NetworkUtilization_Map_Element> numeArray;
if (!SUCCEEDED(InitNetworkAdapterInfo(numeArray)))
return 1;
if (!SUCCEEDED(PopulateNetworkUtilization(numeArray)))
return 2;
for (int i=0; i<120; i++)
{
if (!SUCCEEDED(PopulateNetworkUtilization(numeArray)))
return 2;
// test
vector<NetworkUtilization_Map_Element>::iterator it;
for (it = numeArray.begin(); it != numeArray.end(); it++)
{
cout << "[" << endl;
wcout << "MAC: " << it->MAC << endl;
cout << "index: " << it->interfaceIndex << endl;
cout << "link speed : " << it->linkSpeed << endl;
cout << "usage : " << it->usage << endl;
cout << "]" << endl;
}
Sleep(1000);
}
CoUninitialize();
return 0;
}
到这里这个方案基本就完成了,有心的朋友仔细查一下msdn可能会发现其实MIB_IFROW2的结构体里面就有linkSpeed字段,为什么不用呢?还是上面的话,因为这个结构体只在vista之后的系统中有效。
记得我在以前的一篇博文中提到过这样一个问题,有时我们添加两个虚拟网卡时,两个网卡名称是一样的,这样的结果就是我们无法根据名称去匹配指定的网卡。
通常我们获取网卡的信息有两种方式:1. WMI的win32_networkAdapter类;2. IpHlpApi框架。
而获取网络使用率的方式也有两种:1. performance monitor编程接口;2. Win32_PerfFormattedData_Tcpip_NetworkInterface类。
但是我发现这些方式都没办法解决我以上提到的问题。因为无论是从performance monitor,还是Win32_PerfFormattedData_Tcpip_NetworkInterface来获取网络利用率都是依赖于网卡名。另外,我发现在Windows Task manager里面看的网络使用率和线路速度都匹配的很正常。所以,直觉是觉得应该有一种方式可以比较好的去获取这两个值,无论网卡名是否相同。通过研究发现,其实想要获取这两个值,并且建立匹配关系可以通过WMI和IpHlpApi框架来实现。顺便说一句,我的目标是该程序能运行在win2000以后的所有系统上,所以出于兼容性的考虑,我会放弃那些只支持vista之后操作系统的方案。下面我们具体来看一下,如何用代码来实现:
为了获得WMI和IpHlpApi框架的支持,我们需要包含下面几个头文件和库:
#include <Wbemidl.h>
#include <comdef.h>
#include <Iphlpapi.h>
#pragma comment(lib , "Iphlpapi.lib")
同样为了使用智能指针,我又做了以下声明
代码
int _tmain(int argc, _TCHAR* argv[])
{
CoInitialize(NULL);
vector<NetworkUtilization_Map_Element> numeArray;
if (!SUCCEEDED(InitNetworkAdapterInfo(numeArray)))
return 1;
if (!SUCCEEDED(PopulateNetworkUtilization(numeArray)))
return 2;
for (int i=0; i<120; i++)
{
if (!SUCCEEDED(PopulateNetworkUtilization(numeArray)))
return 2;
// test
vector<NetworkUtilization_Map_Element>::iterator it;
for (it = numeArray.begin(); it != numeArray.end(); it++)
{
cout << "[" << endl;
wcout << "MAC: " << it->MAC << endl;
cout << "index: " << it->interfaceIndex << endl;
cout << "link speed : " << it->linkSpeed << endl;
cout << "usage : " << it->usage << endl;
cout << "]" << endl;
}
Sleep(1000);
}
CoUninitialize();
return 0;
}
到这里这个方案基本就完成了,有心的朋友仔细查一下msdn可能会发现其实MIB_IFROW2的结构体里面就有linkSpeed字段,为什么不用呢?还是上面的话,因为这个结构体只在vista之后的系统中有效。
相关文章推荐
- How to get camped network type name - Android应用如何获得Phone当前注册的网络类型
- 【转载】利用GetNetworkParams函数获取本地网络配置信息
- FileProvider无法获取外置SD卡问题解决方案 | Failed to find configured root that contains
- 修改framework中config.xml的networkAttributes网络资源后导致CTS testGetAllNetworkInfo失败
- [SharePoint]javascript client object model 获取lookup 类型的field的值,包括user类型(单人或者多人)的值。how to get the multiple user type/lookup type field value by Javascript client object model
- Android系列之网络(一)----使用HttpClient发送HTTP请求(通过get方法获取数据)
- Linux下java获取CPU、内存、磁盘IO、网络带宽使用率
- 使用API判断网络是否连通(InternetGetConnectedState / IsNetworkAlive)
- Android系列之网络(一)----使用HttpClient发送HTTP请求(通过get方法获取数据)
- 一个C#编写的snmp程序,可使网络管理人员进行参考、开发-A C# Prepared snmp procedures, will enable network managers to carry o
- 安卓网络编程-通过GET方式获取网络图片
- Android网络电台的一种实现方案
- 连接网络(Connecting to the Network)
- fms 项目目录映射到网络磁盘(Mapping directories to network drives)
- Lecture 9: Ways to make neural networks generalize better 提高神经网络泛化能力的方法
- Linux下java获取CPU、内存、磁盘IO、网络带宽使用率
- 使用API判断网络是否连通(InternetGetConnectedState / IsNetworkAlive)
- 第十二篇:Android GET请求获取网络数据以及POST数据(使用HttpURLConnection)
- 【Android】使用http的Post和Get方式获取网络数据
- The solution to search related problems on Geonetwork: operators, quotes, phrase, chinese.