You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Netapi32库获取网络统计的C语言代码异常求助

问题:NetStatisticsGet()返回结果异常,仅少数字段更新

我想用C语言获取网络统计信息,但调用NetStatisticsGet()函数后,返回状态显示成功,可每次打印缓冲区内容基本一致。单独打印结构体字段时,只有SmbsTransmitted字段每次循环递增1,UseCount、StatisticsStartTime、BytesReceived、BytesTransmitted字段有非零值但始终不变,其余字段全为0。查阅Windows官方文档未找到有效解决方法,求排查问题原因。

完整代码

#include <stdio.h>
#include <windows.h>
#include <lmstats.h>
#include <lmapibuf.h>

NET_API_STATUS status;
LPWSTR lpwsn = L"LanmanWorkstation";
LPBYTE lpBuf;
DWORD dwSize = 0;

int main() {
    while (1) {
        /* Print network stats at 500 ms intervals */
        status = NetStatisticsGet(NULL, lpwsn, 0, 0, &lpBuf);
        printf("lpbuf: %p\n", lpBuf);

        if (status == NERR_Success) {
            LPSTAT_WORKSTATION_0 pStats = (LPSTAT_WORKSTATION_0)lpBuf;
            NetApiBufferSize (lpBuf, &dwSize);

            for (int i = 0; i < dwSize; i++) printf("%02x", lpBuf[i]);
            printf("\n\n");
            
        } else {
            printf("status code %d\n", status);
            return 0;
        }
        Sleep(500);
    }
    NetApiBufferFree(lpBuf);
    return 0;
}

编译命令

gcc netstats.c -lNetapi32

输出结果

lpbuf: 0000025805c75660
432e32876ce0d901307f080000000000850200000000000000000000000000000000000000000000000000000000000000000000000000009e3d08000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000340000000000000000000000000000004c4d454dd800000038d08401f67f00000000000000000000

lpbuf: 0000025805c74000
432e32876ce0d901307f080000000000860200000000000000000000000000000000000000000000000000000000000000000000000000009e3d08000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000340000000000000000000000000000004c4d454dd800000038d08401f67f00000000000000000000

lpbuf: 0000025805c76160
432e32876ce0d901307f080000000000870200000000000000000000000000000000000000000000000000000000000000000000000000009e3d0800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000340000000000000000000000000000004c4d454dd800000038d08401f67f00000000000000000000

lpbuf: 0000025805c768d0
432e32876ce0d901307f080000000000880200000000000000000000000000000000000000000000000000000000000000000000000000009e3d0800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000340000000000000000000000000000004c4d454dd800000038d08401f67f00000000000000000000

问题分析及修复方案

核心问题

  1. 内存泄漏+旧数据缓存:循环中每次调用NetStatisticsGet()都会分配新缓冲区,但从未调用NetApiBufferFree()释放,系统可能因资源限制返回缓存的旧统计数据,同时造成内存泄漏。
  2. 参数错误:NetStatisticsGet()的第四个参数(dwReserved)传0不符合工作站统计的要求,需指定为STAT_WORKSTATION才能获取实时有效数据。
  3. 调试方式低效:直接打印二进制缓冲区难以定位问题,应打印结构体具体字段值来验证数据更新情况。

修复后的代码

#include <stdio.h>
#include <windows.h>
#include <lmstats.h>
#include <lmapibuf.h>

int main() {
    NET_API_STATUS status;
    LPWSTR lpwsn = L"LanmanWorkstation";
    LPBYTE lpBuf = NULL;

    while (1) {
        // 指定STAT_WORKSTATION参数,确保获取实时工作站统计数据
        status = NetStatisticsGet(NULL, lpwsn, 0, STAT_WORKSTATION, &lpBuf);

        if (status == NERR_Success) {
            LPSTAT_WORKSTATION_0 pStats = (LPSTAT_WORKSTATION_0)lpBuf;
            printf("=== 网络统计快照 ===\n");
            printf("SMB发送数: %lu\n", pStats->work_station_0_smbs_transmitted);
            printf("接收字节数: %lu\n", pStats->work_station_0_bytes_received);
            printf("发送字节数: %lu\n", pStats->work_station_0_bytes_transmitted);
            printf("连接计数: %lu\n", pStats->work_station_0_use_count);
            printf("-------------------\n\n");
            
            // 每次循环后释放缓冲区,避免内存泄漏和旧数据缓存
            NetApiBufferFree(lpBuf);
            lpBuf = NULL;
        } else {
            printf("调用失败,错误码: %d\n", status);
            if (lpBuf != NULL) {
                NetApiBufferFree(lpBuf);
            }
            return 1;
        }
        Sleep(500);
    }
    return 0;
}

额外说明

  • 若需要更详细的统计数据,可将NetStatisticsGet()的第三个参数(level)设为1,获取STAT_WORKSTATION_1结构体,该结构体包含更多网络统计字段。
  • NetStatisticsGet()针对不同服务(如LanmanWorkstation、LanmanServer)有不同的参数要求,需根据目标服务选择对应的统计类型标识。

内容的提问来源于stack exchange,提问作者vibhav950

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 12:20:54