zoukankan      html  css  js  c++  java
  • 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
    ");
    		return false;
    	}
    
    	Sleep(1000);
    
    	/*再取*/
    	DWORD dwTotalRecv2 = 0, dwTotalSend2 = 0;
    	if(!GetStatisticOfSysNetworkFlow(dwTotalRecv2, dwTotalSend2))
    	{
    		printf("GetStatisticOfSysNetworkFlow == false
    ");
    		return false;
    	}
    
    	/*计算*/
    	dwbpsRecv = dwTotalRecv2 - dwTotalRecv1;
    	dwbpsSend = dwTotalSend2 - dwTotalSend1;
    
    	return true;
    }

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



  • 相关阅读:
    WPF 中依赖属性的继承(Inherits)
    使用FluentValidation来进行数据有效性验证
    使用ASP.Net WebAPI构建REST服务(六)——Self-Host
    使用ASP.Net WebAPI构建REST服务(五)——客户端
    使用ASP.Net WebAPI构建REST服务(四)——参数绑定
    使用ASP.Net WebAPI构建REST服务(三)——返回值
    使用ASP.Net WebAPI构建REST服务(二)——路由
    使用ASP.Net WebAPI构建REST服务(一)——简单的示例
    WPF在代码中创建DataTemplate时候的异常
    一个简单的WeakList的实现
  • 原文地址:https://www.cnblogs.com/chaikefusibushiji/p/6775765.html
Copyright © 2011-2022 走看看