C++使用GetAdaptersInfo获取本机MAC、IP及子网掩码
在C++ Windows程序开发中,获取本机的网络配置信息(如MAC地址、IP和子网掩码)通常需要调用Win32 API。本文将通过具体代码示例,演示如何利用 iphlpapi.h 中的 GetAdaptersInfo 接口完成这一任务,并处理相关的内存管理。
实现原理与准备
获取网络适配器信息主要依赖Windows提供的 IP Helper API。该方法的核心流程分为三步:首先通过两次调用确定所需缓冲区的大小;其次分配内存并再次调用以填充结构体;最后从 IP_ADAPTER_INFO 结构体中提取所需的网络参数。
需要注意的是,该API仅返回第一个网络适配器的信息(即默认路由接口),对于多网卡环境可能需要遍历列表,但本示例聚焦于基础功能的实现。
代码实现步骤
第1步:引入必要头文件与链接库
为了使用网络相关函数,必须包含 iphlpapi.h 并链接对应的静态库 IPHLPAPI.lib。同时,由于涉及Socket初始化,通常也需要基础的Socket头文件支持。
#include <stdio.h>
#include <iphlpapi.h>
#pragma comment(lib, "IPHLPAPI.lib")
// 假设存在自定义的Socket初始化类
#include "InitSock.h"
第2步:定义全局变量用于存储结果
为方便演示,我们在函数外部定义全局变量来接收获取到的MAC地址(6字节)、网关IP、本地IP和子网掩码。
u_char g_ucLocalMac[6];
DWORD g_dwGatewayIP;
DWORD g_dwLocalIP;
DWORD g_dwMask;
第3步:获取并解析适配器信息
创建 GetGlobalData 函数执行核心逻辑。使用 GetAdaptersInfo 时,初始调用传入NULL指针和0大小,函数会返回实际需要的缓冲区大小。随后使用 GlobalAlloc 分配内存并再次调用获取真实数据。
BOOL GetGlobalData()
{
PIP_ADAPTER_INFO pAdapterInfo = NULL;
ULONG ulSize = 0;
// 第一次调用:获取所需缓冲区大小
::GetAdaptersInfo(pAdapterInfo, &ulSize);
// 分配内存
pAdapterInfo = (PIP_ADAPTER_INFO)::GlobalAlloc(GPTR, ulSize);
// 第二次调用:获取实际数据
if (ERROR_SUCCESS == ::GetAdaptersInfo(pAdapterInfo, &ulSize))
{
if (pAdapterInfo != NULL)
{
// 提取MAC地址(前6字节)
memcpy(g_ucLocalMac, pAdapterInfo->Address, 6);
// 提取网关IP(转换为主机字节序)
g_dwGatewayIP = ::inet_addr(pAdapterInfo->GatewayList.IpAddress.String);
// 提取本地IP
g_dwLocalIP = ::inet_addr(pAdapterInfo->IpAddressList.IpAddress.String);
// 提取子网掩码
g_dwMask = ::inet_addr(pAdapterInfo->IpAddressList.IpMask.String);
}
}
// 打印输出格式化处理
in_addr in;
in.S_un.S_addr = g_dwLocalIP;
printf(" IP Address:%-30s\n", ::inet_ntoa(in));
in.S_un.S_addr = g_dwGatewayIP;
printf(" Gateway Address:%-30s\n", ::inet_ntoa(in));
in.S_un.S_addr = g_dwMask;
printf(" MASK Address:%-30s\n", ::inet_ntoa(in));
u_char* p = g_ucLocalMac;
printf(" MAC:%02X-%02X-%02X-%02X-%02X-%02X\n", p[0], p[1], p[2], p[3], p[4], p[5]);
// 释放内存
::GlobalFree(pAdapterInfo);
pAdapterInfo = NULL;
return TRUE;
}
第4步:主函数调用与环境初始化
在 main 函数中,首先需要初始化WinSock(确保网络栈可用),然后调用上述获取函数。
void main()
{
CInitSock initSock; // 假设此类负责WSAStartup
GetGlobalData();
printf("*******************************");
getchar(); // 暂停以便观察输出
}
注意事项与排查
- 权限问题:在较新的Windows版本中,部分高级网络信息可能受UAC限制,普通管理员权限通常足够,但某些虚拟网卡可能无法读取准确的MAC地址。
- 内存泄漏风险:示例中使用
GlobalAlloc必须在获取成功后或异常时通过GlobalFree释放,否则会导致内存泄漏。现代C++建议使用std::unique_ptr或智能指针进行更安全的资源管理。 - IPv6支持:
GetAdaptersInfo仅支持IPv4。若需获取IPv6地址或处理多网卡完整列表,应改用GetAdaptersAddresses函数。
总结
通过 iphlpapi.h 提供的接口,开发者可以便捷地在C++应用中获取本机基本网络标识。理解缓冲区的两次调用模式是避免崩溃的关键。以上就是利用C++获取本机MAC、IP及MASK地址的详细内容,更多关于C++网络编程的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









