主要知识点: PMIB_IFTABLE结构体、MIB_IFROW结构体、GetIfTable函数
先上代码
#include <windows.h>
#include <Iphlpapi.h>
#include <cstdio>
#pragma comment(lib, "Iphlpapi.lib")
int main()
{
PMIB_IFTABLE m_pTable = NULL;
DWORD m_dwAdapters = 0;
ULONG uRetCode = GetIfTable(m_pTable, &m_dwAdapters, TRUE);
if (uRetCode == ERROR_NOT_SUPPORTED)
{
return (-1);
}
if (uRetCode == ERROR_INSUFFICIENT_BUFFER)
{
m_pTable = (PMIB_IFTABLE)new BYTE[65535]; //假设端口数不超过65535个
}
DWORD dwLastIn = 0; //上一秒钟的接收字节数
DWORD dwLastOut = 0; //上一秒钟的发送字节数
DWORD dwBandIn = 0; //下载速度
DWORD dwBandOut = 0; //上传速度
while (1)
{
system("cls");
GetIfTable(m_pTable, &m_dwAdapters, TRUE);
DWORD dwInOctets = 0;
DWORD dwOutOctets = 0;
//将所有端口的流量进行统计
for (UINT i = 0; i < m_pTable->dwNumEntries; i++)
{
MIB_IFROW Row = m_pTable->table[i];
dwInOctets += Row.dwInOctets;
dwOutOctets += Row.dwOutOctets;
//printf("dwSpeed:%u\n", Row.dwSpeed);
}
dwBandIn = dwInOctets - dwLastIn; //下载速度
dwBandOut = dwOutOctets - dwLastOut; //上传速度
if (dwLastIn <= 0)
{
dwBandIn = 0;
}
else
{
dwBandIn = dwBandIn / 1024.0; //b转换成kb
}
if (dwLastOut <= 0)
{
dwBandOut = 0;
}
else
{
dwBandOut = dwBandOut / 1024.0; //b转换成kb
}
dwLastIn = dwInOctets;
dwLastOut = dwOutOctets;
printf("收到字节: %u bytes\n", dwLastIn);
printf("发送字节: %u bytes\n", dwLastOut);
printf("下行速度: %u KB\n", dwBandIn);
printf("上行速度: %u KB\n", dwBandOut);
printf("--------------------------\n");
Sleep(1000); //休眠一秒钟
}
delete[] m_pTable;
return (0);
}
关键知识点
- MIB_IFROW结构体
语法:
typedef struct _MIB_IFROW {
WCHAR wszName[MAX_INTERFACE_NAME_LEN];
IF_INDEX dwIndex;
IFTYPE dwType;
DWORD dwMtu;
DWORD dwSpeed;
DWORD dwPhysAddrLen;
UCHAR bPhysAddr[MAXLEN_PHYSADDR];
DWORD dwAdminStatus;
INTERNAL_IF_OPER_STATUS dwOperStatus;
DWORD dwLastChange;
DWORD dwInOctets;
DWORD dwInUcastPkts;
DWORD dwInNUcastPkts;
DWORD dwInDiscards;
DWORD dwInErrors;
DWORD dwInUnknownProtos;
DWORD dwOutOctets;
DWORD dwOutUcastPkts;
DWORD dwOutNUcastPkts;
DWORD dwOutDiscards;
DWORD dwOutErrors;
DWORD dwOutQLen;
DWORD dwDescrLen;
UCHAR bDescr[MAXLEN_IFDESCR];
} MIB_IFROW, *PMIB_IFROW;
成员(只解释相关部分):
dwInOctets
类型:DWORD
通过此接口接收的数据的八进制数。
dwOutOctets
类型:DWORD
通过此接口发送的数据的八位字节数。
- PMIB_IFTABLE结构体
语法:
typedef struct _MIB_IFTABLE {
DWORD dwNumEntries;
MIB_IFROW table[ANY_SIZE];
} MIB_IFTABLE, *PMIB_IFTABLE;
成员:
dwNumEntries
数组中的接口条目数。
table[ANY_SIZE]
包含接口条目 的MIB_IFROW 结构的数组。
- GetIfTable函数
结构:
IPHLPAPI_DLL_LINKAGE DWORD GetIfTable(
[out] PMIB_IFTABLE pIfTable,
[in, out] PULONG pdwSize,
[in] BOOL bOrder
);
参数说明:
[out] pIfTable
指向以MIB_IFTABLE结构的形式接收接口表 的缓冲区的 指针。
[in, out] pdwSize
在输入时,指定 pIfTable 参数指向的缓冲区的大小(以字节为单位)。
在输出时,如果缓冲区不够大,无法容纳返回的接口表,则函数会将此参数设置为等于所需的缓冲区大小(以字节为单位)。
[in] bOrder
一个布尔值,指定是否应按接口索引按升序对返回的接口表进行排序。 如果此参数为 TRUE,则对表进行排序。
返回值:
如果函数成功,则返回值NO_ERROR。
如果函数失败,则返回值为以下错误代码之一。
返回代码 说明
ERROR_INSUFFICIENT_BUFFER:pIfTable 参数指向的缓冲区不够大。 所需大小在 pdwSize 参数指向的 DWORD 变量中返回。
ERROR_INVALID_PARAMETER:pdwSize 参数为 NULL,或者 GetIfTable 无法写入 pdwSize 参数指向的内存。
ERROR_NOT_SUPPORTED:本地系统上正在使用的操作系统不支持此函数。
其实就是说传入一个结构体和缓冲区大小值以及一个布尔值,如果你传入的缓冲区大小够大,它就会将所有接口的信息包括流量信息存储到第一个参数的结构体之中,这样你只要调用传回来的结构体就能获取相关信息了