流量用的是GetIfTable()函数, 这个函数获取的东西直接和MIB里的ifTable对应,可惜的是,其Name字段是空的,其他都是有效的。应该通过InOctets和OutOctets来计算流量和带宽。InOctes就是累计收到了字节数,由于是一个累计值,在计算带宽时需要除以一个时间段。假设在时间tDelta内获得了nOctets个字节,那实际速率就是nOctets * 8 / tDelta。乘8是因为网带的单位是bits/s。
Speed字段表示的是该网口的最大速率,一般是100000000或1000000000,即100M或1G。
int WIN_GetIfTable(WIN_IfTable& lstIf)
{
// GetAdaptersAddresses
// 网口信息, 准备1个足够大的buf
struct
{
DWORD dwNumEntries;
MIB_IFROW table[8];
}myIfTable;
memset(&myIfTable, 0, sizeof(myIfTable));
// DWORD nNumOfIf = 0;
// DWORD ret = GetNumberOfInterfaces(&nNumOfIf);
ULONG nBufSize = sizeof(myIfTable);
DWORD ret = GetIfTable((MIB_IFTABLE*)&myIfTable, &nBufSize, TRUE);
if( ret == 0)
{
for(int i=0; i<myIfTable.dwNumEntries; i++)
{
WIN_IfEntry entry;
MIB_IFROW* pRow = &myIfTable.table[i];
strcpy(entry.strName, “”);
strcpy(entry.strDescr, (char*)pRow->bDescr);
entry.nIndex = pRow->dwIndex;
entry.nType = pRow->dwType;
entry.nInOctets = pRow->dwInOctets; //pRow->dwInUcastPkts + pRow->dwInNUcastPkts;
entry.nOutOctes = pRow->dwOutOctets; //pRow->dwOutUcastPkts + pRow->dwOutNUcastPkts;
entry.nAdminStatus = pRow->dwAdminStatus;
entry.nSpeed = pRow->dwSpeed;
if(pRow->dwType == 6)
lstIf.push_back(entry);
}
}
return 0;
}
由于InOctets字段是32bit整数,增至0xFFFFFFFF后会掉头到0,所以要注意减法运算。
inline unsigned int GetWrappedDelta(unsigned int a, unsigned int b)
{
if(a >= b)
return a - b;
else
return (0xFFFFFFFF-b) + a;
}