Qt技术求助:如何通过API获取网络接口的传输名称(GUID)
获取Qt中网络接口的传输名称(GUID)
我明白你的困扰——Qt的QNetworkInterface类确实没有直接提供获取网络接口传输名称(就是你图里高亮的那个GUID格式标识)的API,不过咱们可以结合平台特定的系统API,再用你已经能拿到的MAC地址做匹配,就能拿到这个标识了。下面分平台给你具体的实现方案:
Windows平台实现
在Windows上,我们可以用系统的IP Helper API里的GetAdaptersAddresses函数,它能返回包含GUID(存在AdapterName字段里)的完整网络接口信息,然后通过MAC地址和QNetworkInterface的结果做关联:
#include <QNetworkInterface> #include <windows.h> #include <iphlpapi.h> #include <iostream> // 记得链接iphlpapi库,Qt项目可以在.pro文件加 LIBS += -liphlpapi #pragma comment(lib, "iphlpapi.lib") QString getInterfaceGuidByMac(const QString& macAddress) { // 先把MAC地址转成无分隔符的大写形式,方便后续匹配 QString targetMac = macAddress.remove(':').remove('-').toUpper(); ULONG outBufLen = 0; // 先调用一次获取需要的缓冲区大小 GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, NULL, &outBufLen); PIP_ADAPTER_ADDRESSES pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen); if (!pAddresses) { return QString(); } if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &outBufLen) == NO_ERROR) { PIP_ADAPTER_ADDRESSES pCurrAddresses = pAddresses; while (pCurrAddresses) { if (pCurrAddresses->PhysicalAddressLength > 0) { // 把系统返回的MAC字节数组转成字符串 QString currentMac; for (DWORD i = 0; i < pCurrAddresses->PhysicalAddressLength; i++) { currentMac += QString("%1").arg((BYTE)pCurrAddresses->PhysicalAddress[i], 2, 16, QChar('0')).toUpper(); } // 匹配到目标MAC就返回对应的GUID if (currentMac == targetMac) { QString guid = QString::fromWCharArray(pCurrAddresses->AdapterName); free(pAddresses); return guid; } } pCurrAddresses = pCurrAddresses->Next; } } free(pAddresses); return QString(); } // 调用示例 int main() { foreach(QNetworkInterface interface, QNetworkInterface::allInterfaces()) { if (!interface.hardwareAddress().isEmpty()) { QString guid = getInterfaceGuidByMac(interface.hardwareAddress()); qDebug() << "MAC:" << interface.hardwareAddress() << "GUID:" << guid; } } return 0; }
Linux/macOS平台实现
Linux上没有和Windows完全一样的GUID,但可以获取接口的持久化标识(比如sysfs里的路径),macOS则可以通过系统框架拿到类似的唯一标识。这里用Linux的示例,核心是通过QNetworkInterface拿到的接口名去关联系统文件:
#include <QNetworkInterface> #include <QFile> #include <QString> QString getInterfacePersistentId(const QString& interfaceName) { // 读取sysfs里的设备信息文件 QString path = QString("/sys/class/net/%1/device/uevent").arg(interfaceName); QFile file(path); if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { QString content = file.readAll(); file.close(); // 提取DEVPATH作为持久化标识,这个在系统重启后也不会变 QStringList lines = content.split('\n'); foreach(QString line, lines) { if (line.startsWith("DEVPATH=")) { return line.mid(8); } } } // macOS下可以用SystemConfiguration框架的SCNetworkInterfaceCopyAll接口,这里就不展开写了 return QString(); } // 调用示例 int main() { foreach(QNetworkInterface interface, QNetworkInterface::allInterfaces()) { if (!interface.hardwareAddress().isEmpty()) { QString persistentId = getInterfacePersistentId(interface.name()); qDebug() << "MAC:" << interface.hardwareAddress() << "Persistent ID:" << persistentId; } } return 0; }
小提示
- 跨平台项目记得用
#ifdef Q_OS_WIN、#ifdef Q_OS_LINUX、#ifdef Q_OS_MAC把不同平台的代码隔开,避免编译错误。 - Windows下运行程序可能需要管理员权限,不然可能获取不到完整的接口信息。
- Qt项目里加链接库的话,直接在.pro文件里加
LIBS += -liphlpapi就行。
内容的提问来源于stack exchange,提问作者sonulohani
相关产品推荐
相关产品推荐

