本文描述了如何去获取本机的所有网卡的IP地址和网卡的速率,可以根据速度来确定属于千兆网或万兆网,具体实现代码如下:
#include <WinSock2.h>
#include <Iphlpapi.h>
#include <tchar.h>
#include <windows.h>
#include <pdh.h>
#include
using namespace std;
#pragma comment(lib,“Iphlpapi.lib”) //需要添加Iphlpapi.lib库
#pragma comment(lib, “pdh.lib”)
std::vector t_VecNetWorkInfo;
NetWorkInfo t_NetWorkInfo;
//获取本地IP
QStringList strIPList;
PIP_ADAPTER_INFO pIpAdapterInfo = new IP_ADAPTER_INFO();//PIP_ADAPTER_INFO结构体指针存储本机网卡信息
unsigned long stSize = sizeof(IP_ADAPTER_INFO); //得到结构体大小,用于GetAdaptersInfo参数
int nRel = GetAdaptersInfo(pIpAdapterInfo, &stSize); //调用GetAdaptersInfo函数,填充pIpAdapterInfo指针变量;其中stSize参数既是一个输入量也是一个输出量
if (ERROR_BUFFER_OVERFLOW == nRel)
{
//如果函数返回的是ERROR_BUFFER_OVERFLOW
//则说明GetAdaptersInfo参数传递的内存空间不够,同时其传出stSize,表示需要的空间大小
//这也是说明为什么stSize既是一个输入量也是一个输出量
delete pIpAdapterInfo;//释放原来的内存空间
pIpAdapterInfo = (PIP_ADAPTER_INFO)new BYTE[stSize];//重新申请内存空间用来存储所有网卡信息
nRel = GetAdaptersInfo(pIpAdapterInfo, &stSize); //再次调用GetAdaptersInfo函数,填充pIpAdapterInfo指针变量
}
if (ERROR_SUCCESS == nRel)
{
//输出网卡信息
//可能有多网卡,因此通过循环去判断
while (pIpAdapterInfo)
{
memcpy(t_NetWorkInfo.AdapterName, pIpAdapterInfo->AdapterName, sizeof(pIpAdapterInfo->AdapterName));
memcpy(t_NetWorkInfo.Description, pIpAdapterInfo->Description, sizeof(pIpAdapterInfo->Description));
//可能网卡有多IP,因此通过循环去判断
IP_ADDR_STRING *pIpAddrString = &(pIpAdapterInfo->IpAddressList);
if (pIpAddrString != nullptr)
{
do
{
t_NetWorkInfo.IpAddrString.push_back(pIpAddrString->IpAddress);
//cout << "IP 地址:" << pIpAddrString->IpAddress.String << endl;
pIpAddrString = pIpAddrString->Next;
} while (pIpAddrString);
}
pIpAdapterInfo = pIpAdapterInfo->Next;
t_VecNetWorkInfo.push_back(t_NetWorkInfo);
}
}
//释放内存空间
if (pIpAdapterInfo)
{
delete pIpAdapterInfo;
}
HQUERY hQuery = NULL;
PDH_STATUS pdhStatus;
HCOUNTER * pCounterHandle = NULL;
pdhStatus = PdhOpenQuery(0, 0, &hQuery);
if (pdhStatus != ERROR_SUCCESS)
{
return;
}
pCounterHandle = (HCOUNTER*)GlobalAlloc(GPTR, sizeof(HCOUNTER));
if (pCounterHandle == NULL)
{
return;
}
PDH_FMT_COUNTERVALUE fmtValue;
DWORD dwctrType;
DWORD dwCountListLen = NULL;
DWORD dwInstandeListLen = NULL;
LPTSTR lpCounterList = NULL;
LPTSTR lpInstanceList = NULL;
LPTSTR lpString = NULL;
TCHAR szCountPath[256] = { 0 };
TCHAR szMsg[128] = { 0 };
PdhEnumObjectItems(NULL, NULL, TEXT("Network Interface"), lpCounterList, &dwCountListLen, lpInstanceList, &dwInstandeListLen, PERF_DETAIL_WIZARD, 0);
lpCounterList = new TCHAR[dwCountListLen];
lpInstanceList = new TCHAR[dwInstandeListLen];
pdhStatus = PdhEnumObjectItems(NULL, NULL, TEXT("Network Interface"), lpCounterList, &dwCountListLen, lpInstanceList, &dwInstandeListLen, PERF_DETAIL_WIZARD, 0);
if (pdhStatus != ERROR_SUCCESS)
{
return;
}
for (lpString = lpInstanceList; *lpString != 0; lpString += lstrlen(lpString) + 1)
{
if (_tcscmp(lpString, TEXT("MS TCP Loopback interface")) == 0)
{
continue;
}
_stprintf_s(szCountPath, _countof(szCountPath), _TEXT("\\Network Interface(%s)\\Current Bandwidth"), lpString);
pdhStatus = PdhAddCounter(hQuery, szCountPath, 0, pCounterHandle);
if (pdhStatus != ERROR_SUCCESS)
{
return;
}
pdhStatus = PdhCollectQueryData(hQuery);
if (pdhStatus != ERROR_SUCCESS)
{
return;
}
pdhStatus = PdhGetFormattedCounterValue(*pCounterHandle, PDH_FMT_LARGE, &dwctrType, &fmtValue);
if (pdhStatus != ERROR_SUCCESS)
{
return;
}
char str[MAX_ADAPTER_DESCRIPTION_LENGTH + 4];
TcharToChar(lpString, str);
std::string strString(str);
string::size_type pos(0);
if ((pos = strString.find("[")) != string::npos)
{
strString.replace(pos, 1, "(");
}
if ((pos = strString.find("]")) != string::npos)
{
strString.replace(pos, 1, ")");
}
for (int i = 0; i < t_VecNetWorkInfo.size(); ++i)
{
if (fmtValue.largeValue == 1000 * 1000 * 1000 && strcmp(strString.c_str(), t_VecNetWorkInfo.at(i).Description) == 0)
{
for (int j = 0; j < t_VecNetWorkInfo.at(i).IpAddrString.size(); ++j)
{
strIPList.append(QString(t_VecNetWorkInfo.at(i).IpAddrString.at(j).String));
}
}
}
}
delete[] lpCounterList;
delete[] lpInstanceList;
PdhCloseQuery(hQuery);