推荐使用 getifaddrs(Linux/macOS)和 GetAdaptersAddresses(Windows)获取网卡名,避免解析 ifconfig/ip 命令;需注意内存释放、字符编码、接口过滤及跨平台兼容性。

用 getifaddrs 遍历网卡接口(Linux/macOS 推荐)
Linux 和 macOS 下最可靠的方式是调用 getifaddrs,它能返回所有已配置的网络接口信息,包括未启用但存在设备的接口(比如 lo、eth0、wlan0),且无需 root 权限。
关键点:返回的链表中每个 ifaddrs 结构体的 ifa_name 字段就是网卡名称;需注意过滤重复项(同一接口可能有 IPv4/IPv6 多条记录),且必须调用 freeifaddrs 释放内存。
常见错误:ifa_name 是字符串指针,直接打印即可,别误当成需要解析的地址;漏掉 freeifaddrs 会导致内存泄漏。
- 只遍历
AF_PACKET或AF_INET类型的条目就能覆盖绝大多数物理/虚拟网卡 - 跳过以
lo开头但非lo本体的接口(如lo:0)——那是别名,不是独立网卡 - macOS 上部分隧道接口(如
utun0)也会被列出,属于正常行为
Windows 下用 GetAdaptersAddresses(而非 GetAdaptersInfo)
GetAdaptersInfo 已废弃,不支持 IPv6 地址和某些新接口类型(如 WSL2 虚拟网卡),必须用 GetAdaptersAddresses。它返回的是 IP_ADAPTER_ADDRESSES 链表,其中 AdapterName 是内部标识符(如 {xxxxx-...}),而真正可读的名称在 FriendlyName 字段里。
立即学习“C++免费学习笔记(深入)”;
常见错误:直接打印 AdapterName 导致输出一串 GUID;没检查 dwSize 返回值为 ERROR_BUFFER_OVERFLOW 就直接访问缓冲区;忽略 Flags & IP_ADAPTER_NO_MULTICAST 可能漏掉某些禁用多播但实际可用的网卡。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 调用前先传
NULL获取所需缓冲区大小,再分配内存重试 - 用
ConvertInterfaceLuidToName可将 LUID 转为传统名称(如Ethernet),但FriendlyName更直观且含本地化 - 若只需英文名,可取
AdapterName对应的注册表路径HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Network\{...}\Connection下的Name值,但太重,不推荐
跨平台封装要注意的三件事
如果写通用代码,别试图用预编译宏硬切两套逻辑。更稳妥的做法是:Linux/macOS 走 getifaddrs,Windows 走 GetAdaptersAddresses,并统一返回 std::vector<:string></:string> 的名称列表。
容易被忽略的细节:
- Windows 的
FriendlyName可能含宽字符(WCHAR*),必须用WideCharToMultiByte转 UTF-8 或至少转为std::string(使用当前系统代码页) - 某些容器环境(Docker、Podman)或 WSL 中,
lo可能是唯一可见接口,这不是 bug,是网络命名空间隔离导致的 - 不要依赖名称“一定包含 eth/wlan/ens”等前缀判断物理性——虚拟机网卡(
virbr0)、桥接(br-xxx)、DPDK 接口(dpdk0)都可能出现在列表里
为什么不用 ifconfig 或 ip link 解析命令输出
调用 shell 命令拿网卡名看似简单,但实际埋坑很多:输出格式随发行版/版本变化(如 Ubuntu 22.04 的 ip -o link 和 CentOS 7 的 ip link 行数不一致),中文 locale 下字段名可能乱码,还涉及子进程创建开销和信号安全问题。
除非你明确只要快速脚本且只跑在固定环境,否则绕过系统 API 直接解析命令输出,等于把维护成本推给未来自己。
真正难的不是“怎么拿到名字”,而是“怎么确定这个名字对应一个当前可用、能配 IP、可路由的接口”——那得继续查 ifa_flags(Linux)或 OperStatus(Windows),这已经超出单纯“获取名称”的范围了。

















