Windows下c++获取网卡的下行流量、丢包率、错包率

我想实时获取Windows网卡的下行流量、丢包率、错包率的信息,用c/c++语言

img

#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <windows.h>
#include <netioapi.h>
#include <locale.h>
#include <inttypes.h>

#pragma comment(lib, "iphlpapi.lib")

void show_row(PMIB_IF_ROW2 row){
    if(!row->InterfaceAndOperStatusFlags.HardwareInterface)return;
    if(!row->InterfaceAndOperStatusFlags.ConnectorPresent)return;
    wprintf(L"%ls\n", row->Alias);
    wprintf(L"接收字节数 %"PRIu64"\n", row->InUcastOctets);
    wprintf(L"发送字节数 %"PRIu64"\n", row->OutUcastOctets);
    wprintf(L"接收单播包数 %"PRIu64"\n", row->InUcastPkts);
    wprintf(L"发送单播包数 %"PRIu64"\n", row->OutUcastPkts);
    wprintf(L"接收多播包数 %"PRIu64"\n", row->InNUcastPkts);
    wprintf(L"发送多播包数 %"PRIu64"\n", row->OutNUcastPkts);
    wprintf(L"接收错误包数 %"PRIu64"\n", row->InErrors);    
    wprintf(L"发送错误包数 %"PRIu64"\n", row->OutErrors);
    wprintf(L"接收丢包数 %"PRIu64"\n", row->InDiscards);    
    wprintf(L"发送丢包数 %"PRIu64"\n", row->OutDiscards);

    ULONG64 error = row->InErrors + row->OutErrors;
    ULONG64 discard = row->InDiscards + row->OutDiscards;
    ULONG64 total = row->InUcastPkts + row->OutUcastPkts + row->InNUcastPkts + row->OutNUcastPkts + error + discard;
    double error_rate = total?((double)error / (double)total):0;
    double discard_rate = total?((double)discard / (double)total):0;
    
    wprintf(L"错误率 %.4f\n", error_rate);
    wprintf(L"丢包率 %.4f\n", discard_rate);
    printf("\n");
}

void show_table(PMIB_IF_TABLE2 table){
    int i;
    PMIB_IF_ROW2 row;
    for (i = 0; i < table->NumEntries; i++){
        row = &table->Table[i];
        show_row(row);
    }
}

void get_if_status(){
    PMIB_IF_TABLE2 table;
    if(0 == GetIfTable2Ex(MibIfTableNormal, &table)){
        show_table(table);
        FreeMibTable(table);
    }else{
        printf("GetIfTable2Ex fail %d\n", (int)GetLastError());
    }
}

int main(){
    setlocale(0,"");
    while(1){
        get_if_status();        
        Sleep(2000);
        system("cls");
    }
    return 0;
}

参考 https://blog.csdn.net/bbdxf/article/details/79088207

要实时获取Windows网卡的下行流量、丢包率和错包率的信息,您可以使用Windows API来实现。以下是一种可能的实现方法:

  1. 包含所需的头文件:

    #include <windows.h>
    #include <iphlpapi.h>
    #include <iostream>
    #pragma comment(lib, "iphlpapi.lib")
    
  2. 定义一个函数来获取网卡的下行流量、丢包率和错包率:

    void GetNetworkStats()
    {
     MIB_IFROW ifRow;
     ifRow.dwIndex = 1; // 网卡索引,这里假设为1
    
     if (GetIfEntry(&ifRow) == NO_ERROR)
     {
         ULONGLONG bytesSent = ifRow.dwOutOctets;  // 下行流量,以字节为单位
         ULONGLONG bytesReceived = ifRow.dwInOctets;  // 上行流量,以字节为单位
         DWORD packetSent = ifRow.dwOutDiscards;  // 发送丢包数
         DWORD packetReceived = ifRow.dwInDiscards;  // 接收丢包数
         DWORD packetError = ifRow.dwInErrors;  // 接收错误包数
    
         // 计算丢包率和错包率
         double packetLossRate = 0.0;
         double packetErrorRate = 0.0;
         if (bytesSent > 0)
         {
             packetLossRate = static_cast<double>(packetSent) / bytesSent;
             packetErrorRate = static_cast<double>(packetError) / bytesReceived;
         }
    
         // 输出结果
         std::cout << "下行流量(字节): " << bytesSent << std::endl;
         std::cout << "丢包率: " << packetLossRate << std::endl;
         std::cout << "错包率: " << packetErrorRate << std::endl;
     }
    }
    
  3. 在主函数中调用该函数:

    int main()
    {
     GetNetworkStats();
    
     return 0;
    }
    

请注意,这只是一个简单的示例,您可能需要根据您的具体需求进行适当的修改和扩展。此外,还需要确保您的应用程序以管理员权限运行,以便访问网络接口的统计信息。

另外,这里使用了iphlpapi.lib库文件,因此需要在编译时链接该库。可以使用以下命令进行编译:

g++ your_program.cpp -liphlpapi -o your_program

希望这能帮助到您获取Windows网卡的相关信息。

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 这有个类似的问题, 你可以参考下: https://ask.csdn.net/questions/7397343
  • 这篇博客也不错, 你可以看下Windows下C++动态监测网络变化(对标Windows网络托盘图标)
  • 您还可以看一下 WangTeacher老师的C/C++入门编程介绍合集课程中的 Windows开发环境搭建小节, 巩固相关知识点
  • 以下回答来自chatgpt:

    对于优化后的问题,你应该使用Windows API来实时获取网卡的下行流量、丢包率和错包率的信息。以下是可能的解决方案:

    1. 使用GetIfTable函数获取当前系统中所有网卡的信息。
    2. 遍历网卡列表,并使用GetIfEntry函数获取每个网卡的详细信息,包括接收的总字节数、丢包数和错包数。
    3. 获取前一个时间点的接收总字节数、丢包数和错包数,并计算与当前时间点的差值,即可得出实时的下行流量、丢包率和错包率。

    以下是示例代码:

    #include <iostream>
    #include <iomanip>
    #include <windows.h>
    #include <iphlpapi.h>
    
    #pragma comment(lib, "IPHLPAPI.lib")
    
    void PrintNetworkInterfacesInfo()
    {
        // 获取网卡列表
        MIB_IFTABLE* pIfTable = nullptr;
        DWORD dwSize = 0;
    
        // 第一次调用获取pIfTable所需的缓冲区大小
        if (GetIfTable(pIfTable, &dwSize, FALSE) == ERROR_INSUFFICIENT_BUFFER)
        {
            pIfTable = (MIB_IFTABLE*)malloc(dwSize);
            // 第二次调用获取pIfTable的实际大小数据
            if (GetIfTable(pIfTable, &dwSize, FALSE) == NO_ERROR)
            {
                // 遍历网卡列表,获取每个网卡的详细信息
                for (DWORD i = 0; i < pIfTable->dwNumEntries; i++)
                {
                    MIB_IFROW* pIfRow = &pIfTable->table[i];
    
                    // 获取网卡名称
                    std::string interfaceName(pIfRow->wszName);
    
                    // 获取接收的总字节数、丢包数和错包数
                    DWORD lastBytesReceived = pIfRow->dwInOctets;
                    DWORD lastPacketsDropped = pIfRow->dwInDiscards;
                    DWORD lastPacketsErrors = pIfRow->dwInErrors;
    
                    // 在这里你可以进行一些处理,比如计算流量、丢包率和错包率等
    
                    // 输出网卡信息
                    std::cout << "Interface: " << interfaceName << "\n";
                    std::cout << "Bytes Received: " << lastBytesReceived << "\n";
                    std::cout << "Packets Dropped: " << lastPacketsDropped << "\n";
                    std::cout << "Packets Errors: " << lastPacketsErrors << "\n\n";
                }
            }
    
            free(pIfTable);
        }
    }
    
    int main()
    {
        // 打印网卡信息
        PrintNetworkInterfacesInfo();
    
        return 0;
    }
    

    请注意,上述代码只是一个示例,你可能需要根据实际情况进行修改和优化。此外,你还需要在编译时链接IPHLPAPI.lib库,以便使用相关的Windows API函数。

    希望以上信息对你有帮助!如果你还有其他问题,请随时提问。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

很好实现