Конференция "Сети" » Глупый вопрос про подсчет трафика и GetIfTable [D7, WinXP]
 
  • __Алексей__ (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 это как-то решилось.

    Буду рад любым соображением Мастеров по этому вопросу.
    Спасибо.
  • DVM © (07.10.09 23:27) [1]
    Вероятно, надо ловить те моменты когда счетчик пересекает какое либо значение, количество пересечений запоминать (overflowcounter). Далее все просто:

    bytes = overflowcounter * 4,294,967,295 + currentcounter.
  • DVM © (07.10.09 23:33) [2]
    вот тут еще посмотри, там вроде проблема эта решена: 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 - прошлое значение + текущее.
    Вроде так.
  • DVM © (08.10.09 00:22) [4]

    > __Алексей__   (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 и не такие потоки информации уже ходили по проводам.

    Ладно, придется извращаться. :)
  • DVM © (08.10.09 11:11) [6]

    > __Алексей__   (08.10.09 10:33) [5]


    > А на счет примера:


    > ничего тут тоже не решено. Слетает значение после 4,2 Г.
    >  

    Странно, мне показалось, там в коде есть как раз счетчик переходов через MAXDWORD. Ну да ладно, неважно, все уже равно ясно как делать надо.
 
Конференция "Сети" » Глупый вопрос про подсчет трафика и GetIfTable [D7, WinXP]
Есть новые Нет новых   [134437   +29][b:0][p:0.003]