windows获取系统网络流量

函数

  DWORD GetIfTable(
         PMIB_IFTABLE pIfTable,
         PULONG pdwSize,
         BOOL bOrder
  );


功能

  获取MIB-II接口列表


参数

  PMIB_IFTABLE pIfTable:接收缓冲区,接收GetIfTable返回的MIB-II接口表

  PULONG pdwSize:pIfTable缓冲区字节数,若缓冲区过小则返回所需大小

  BOOL bOrder:指定pIfTable中返回的接口列表条目是否根据接口索引排序

MIB_IFTABLE结构体

typedef struct _MIB_IFTABLE {  
  DWORD     dwNumEntries;  
  MIB_IFROW table[ANY_SIZE];  
} MIB_IFTABLE, *PMIB_IFTABLE;  
  
typedef struct _MIB_IFROW {  
  WCHAR wszName[MAX_INTERFACE_NAME_LEN];  
  DWORD dwIndex;  
  DWORD dwType;  
  DWORD dwMtu;  
  DWORD dwSpeed;  
  DWORD dwPhysAddrLen;  
  BYTE  bPhysAddr[MAXLEN_PHYSADDR];  
  DWORD dwAdminStatus;  
  DWORD 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;  
  BYTE  bDescr[MAXLEN_IFDESCR];  
} MIB_IFROW, *PMIB_IFROW;  

http://msdn.microsoft.com/en-us/library/windows/desktop/aa366836(v=vs.85).aspx

返回值

  成功返回NO_ERROR,否则返回值即错误码


头文件和引用库

  #include <IPHlpApi.h>   
  #pragma comment(lib, "IPHlpApi.lib")


使用方法


/*获取MIB-II接口表大小*/  
DWORD dwBufferLen = 0;  
GetIfTable(NULL, &dwBufferLen, 0);   
  
/*创建MIB-II接口表*/  
PMIB_IFTABLE pMibIfTable = (MIB_IFTABLE*)malloc(dwBufferLen);  
  
/*获取MIB-II接口表*/  
DWORD dwRet = GetIfTable(pMibIfTable, &dwBufferLen, 0);  
if(NO_ERROR != dwRet)  
{  
    std::cout<<"GetIfTable != NO_ERROR, ErrorCode="<<dwRet<<std::endl;  
    free(pMibIfTable);  
    return false;  
}
细说MIB_IFROW结构体成员

  dwType:接口类型,例如IF_TYPE_ETHERNET_CSMACD=6, Ethernet网络接口;IF_TYPE_SOFTWARE_LOOPBACK=24,软件回环测试网络接口。23号之前的网络接口可用来统计系统流量

  dwSpeed:接口速度,单位bps,可用来计算网络带宽

  bPhysAddr:接口网卡的MAC地址

  dwInOctets:接收的字节数,自系统启动,可用来统计系统网络流量。
  dwOutOctets:发送的字节数,自系统启动,可用来统计系统网络流量。

获取网络带宽

bool GetNetworkBandwithByMidTable(int &iMbsBandwidth)  
{  
    /*获取MIB-II接口表大小*/  
    DWORD dwBufferLen = 0;  
    GetIfTable(NULL, &dwBufferLen, 0);   
  
    /*创建MIB-II接口表*/  
    PMIB_IFTABLE pMibIfTable = (MIB_IFTABLE*)malloc(dwBufferLen);  
  
    /*获取MIB-II接口表*/  
    DWORD dwRet = GetIfTable(pMibIfTable, &dwBufferLen, 0);  
    if(NO_ERROR != dwRet)  
    {  
        std::cout<<"GetIfTable != NO_ERROR, ErrorCode="<<dwRet<<std::endl;  
        free(pMibIfTable);  
        return false;  
    }  
  
    iMbsBandwidth = INT_MAX;  
  
    /*多网卡*/  
    for(int i = 0; i != pMibIfTable->dwNumEntries; ++i)  
    {  
        if (pMibIfTable->table[i].dwType <= 23)  
        {  
            int iTmp = static_cast<int>(pMibIfTable->table[i].dwSpeed/1000/1000);  
            if(iTmp != 0 && iTmp < iMbsBandwidth)  
                iMbsBandwidth = iTmp;  
        }  
    }  
  
    free(pMibIfTable);  
    if(iMbsBandwidth == INT_MAX)  
        return false;  
    return true;  
}

网卡的传输速度有10Mbps、100Mbps、1000Mbps,查看网卡速度的方法:设备管理器—网络适配器—选择网卡—属性—高级—连接速度和双工模式—值—下拉菜单中的最大值。

网络带宽由多种因素决定,例如为连接在只具备100M传输速度的双绞线上的计算机配置1000M的网卡就是一种浪费,因为其至多也只能实现100M的传输速率。

故网络带宽为各种物理介质中的最小值,可认为是所有网卡传输速度的最小值(且不为0)。


获取发送比特数和接收比特数,自系统启动


bool GetStatisticOfSysNetworkFlow(DWORD &dwbitTotalRecv, DWORD &dwbitTotalSend)  
{  
    /*获取MIB-II接口表大小*/  
    DWORD dwBufferLen = 0;  
    GetIfTable(NULL, &dwBufferLen, 0);   
  
    /*创建MIB-II接口表*/  
    PMIB_IFTABLE pMibIfTable = (MIB_IFTABLE*)malloc(dwBufferLen);  
  
    /*获取MIB-II接口表*/  
    DWORD dwRet = GetIfTable(pMibIfTable, &dwBufferLen, 0);  
    if(NO_ERROR != dwRet)  
    {  
        std::cout<<"GetIfTable != NO_ERROR, ErrorCode="<<dwRet<<std::endl;  
        free(pMibIfTable);  
        return false;  
    }  
  
    dwbitTotalRecv = dwbitTotalSend = 0;  
  
    /*多网卡*/  
    for(int i = 0; i != pMibIfTable->dwNumEntries; ++i)  
    {  
        if (pMibIfTable->table[i].dwType <= 23)  
        {  
            dwbitTotalRecv += pMibIfTable->table[i].dwInOctets;  
            dwbitTotalSend += pMibIfTable->table[i].dwOutOctets;  
        }  
    }  
  
    /*Byte转bit*/  
    dwbitTotalRecv *= 8;  
    dwbitTotalSend *= 8;  
  
    free(pMibIfTable);  
    return true;  
} 

计算每秒发送比特数和每秒接收比特数

bool GetSysNetworkFlowByMidTable(DWORD &dwbpsRecv, DWORD &dwbpsSend)  
{  
    /*首次获取*/  
    DWORD dwTotalRecv1 = 0, dwTotalSend1 = 0;  
    if(!GetStatisticOfSysNetworkFlow(dwTotalRecv1, dwTotalSend1))  
    {  
        printf("GetStatisticOfSysNetworkFlow == false\n");  
        return false;  
    }  
  
    Sleep(1000);  
  
    /*再取*/  
    DWORD dwTotalRecv2 = 0, dwTotalSend2 = 0;  
    if(!GetStatisticOfSysNetworkFlow(dwTotalRecv2, dwTotalSend2))  
    {  
        printf("GetStatisticOfSysNetworkFlow == false\n");  
        return false;  
    }  
  
    /*计算*/  
    dwbpsRecv = dwTotalRecv2 - dwTotalRecv1;  
    dwbpsSend = dwTotalSend2 - dwTotalSend1;  
  
    return true;  
} 

注:Windows Performance Counter性能计数器的Network Interface对象能够获取系统网络数据,经验证在Win7下Performance Counter可能不存在Network Interface对象,导致程序运行失败。


转载自:https://blog.csdn.net/rongxiaojun1989/article/details/42395687

猜你喜欢

转载自blog.csdn.net/u011731378/article/details/80196310