使用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
问题分析及修复方案
核心问题
- 内存泄漏+旧数据缓存:循环中每次调用
NetStatisticsGet()都会分配新缓冲区,但从未调用NetApiBufferFree()释放,系统可能因资源限制返回缓存的旧统计数据,同时造成内存泄漏。 - 参数错误:
NetStatisticsGet()的第四个参数(dwReserved)传0不符合工作站统计的要求,需指定为STAT_WORKSTATION才能获取实时有效数据。 - 调试方式低效:直接打印二进制缓冲区难以定位问题,应打印结构体具体字段值来验证数据更新情况。
修复后的代码
#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
相关产品推荐
相关产品推荐

