-
__Алексей__ (07.10.09 22:34) [0]Собираю статистику по загрузке сетевых интерфейсов локальной машины. Использую функцию GetIfTable из IPHLPAPI.DLL.
В МСДН структура записи для каждого интерфейса представлена в виде:
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;
Искомые поля dwInOctets, dwOutOctets объявлены типом DWORD, максимальное значение которого, как известно есть 4294967295. Или на языке трафика - 4,2 Гбайта.
Внимание, вопрос: Как же быть с подсчетом трафика в случае, если объем трафика перевалит за 4Г? Сегодня это как закачка одного фильма. Как я понимаю, значение при достижении своего максимума обнулиться. Неужели MS ничего не переделало в этом отношнении. Или у меня может МСДН старый?
Есть подозрение, что Win64 это как-то решилось.
Буду рад любым соображением Мастеров по этому вопросу.
Спасибо. -
Вероятно, надо ловить те моменты когда счетчик пересекает какое либо значение, количество пересечений запоминать (overflowcounter). Далее все просто:
bytes = overflowcounter * 4,294,967,295 + currentcounter. -
вот тут еще посмотри, там вроде проблема эта решена: http://www.delphisources.ru/files/sources/internet/nettrafmonitor.zip
-
__Алексей__ (08.10.09 00:05) [3]За пример спасибо. Изучу обязательно. Но похоже, сам ответ нашел уже. Зря я на MS наехал :) Начиная с windows vista в IPHLPAPI.DLL реализована функция GetIfTable2Ex. Она на вход "проглатывает" вот такую структуру:
typedef struct _MIB_IF_ROW2 {
NET_LUID InterfaceLuid;
NET_IFINDEX InterfaceIndex;
GUID InterfaceGuid;
WCHAR Alias[IF_MAX_STRING_SIZE + 1];
WCHAR Description[IF_MAX_STRING_SIZE + 1];
ULONG PhysicalAddressLength;
UCHAR PhysicalAddress[IF_MAX_PHYS_ADDRESS_LENGTH];
UCHAR PermanentPhysicalAddress[IF_MAX_PHYS_ADDRESS_LENGTH];
ULONG Mtu;
IFTYPE Type;
TUNNEL_TYPE TunnelType;
NDIS_MEDIUM MediaType;
NDIS_PHYSICAL_MEDIUM PhysicalMediumType;
NET_IF_ACCESS_TYPE AccessType;
NET_IF_DIRECTION_TYPE DirectionType;
struct {
BOOLEAN HardwareInterface :1;
BOOLEAN FilterInterface :1;
BOOLEAN ConnectorPresent :1;
BOOLEAN NotAuthenticated :1;
BOOLEAN NotMediaConnected :1;
BOOLEAN Paused :1;
BOOLEAN LowPower :1;
BOOLEAN EndPointInterface :1;
} InterfaceAndOperStatusFlags;
IF_OPER_STATUS OperStatus;
NET_IF_ADMIN_STATUS AdminStatus;
NET_IF_MEDIA_CONNECT_STATE MediaConnectState;
NET_IF_NETWORK_GUID NetworkGuid;
NET_IF_CONNECTION_TYPE ConnectionType;
ULONG64 TransmitLinkSpeed;
ULONG64 ReceiveLinkSpeed;
ULONG64 InOctets;
ULONG64 InUcastPkts;
ULONG64 InNUcastPkts;
ULONG64 InDiscards;
ULONG64 InErrors;
ULONG64 InUnknownProtos;
ULONG64 InUcastOctets;
ULONG64 InMulticastOctets;
ULONG64 InBroadcastOctets;
ULONG64 OutOctets;
ULONG64 OutUcastPkts;
ULONG64 OutNUcastPkts;
ULONG64 OutDiscards;
ULONG64 OutErrors;
ULONG64 OutUcastOctets;
ULONG64 OutMulticastOctets;
ULONG64 OutBroadcastOctets;
ULONG64 OutQLen;
}MIB_IF_ROW2, *PMIB_IF_ROW2;
где все что надо есть 64 разрядное. Тока вот придется для winxp другой код писать :)
пока так представляю. Запоминать предыдущее значение. Если текущее меньше предыдущего, а оно в свою очередь больше 4 000 000 000 (не думаю, что за интервал в 1 минуту проскочит больше 200 Мб), то был сброс значения и разница составляет как раз MAXDWORD - прошлое значение + текущее.
Вроде так. -
> __Алексей__ (08.10.09 00:05) [3]
> не думаю, что за интервал в 1 минуту проскочит больше 200
> Мб
На гигабитном ethernet может и больше проскочить. Там однако 100 Мбайт/сек предел. А есть еще 10 Гбит. -
__Алексей__ (08.10.09 10:33) [5]
> На гигабитном ethernet может и больше проскочить
это тоже нужно учесть.
А на счет примера:
> вот тут еще посмотри, там вроде проблема эта решена: http:
> //www.delphisources.ru/files/sources/internet/nettrafmonitor.zip
ничего тут тоже не решено. Слетает значение после 4,2 Г.
Вообще странно, что МС только с Висты подумало об увеличении разрядности своих счетчиков (ну или разрядности структур API). Посмотрел эти счетчики через WMI и SNMP - та же ботва - обнуляются...
Может сами счетчики в недрах и x64, но вот winAPI явно подотстало в плане их обработки. В года выхода winxp или 2k и не такие потоки информации уже ходили по проводам.
Ладно, придется извращаться. :) -
> __Алексей__ (08.10.09 10:33) [5]
> А на счет примера:
> ничего тут тоже не решено. Слетает значение после 4,2 Г.
>
Странно, мне показалось, там в коде есть как раз счетчик переходов через MAXDWORD. Ну да ладно, неважно, все уже равно ясно как делать надо.