Windows下使用QUdpSocket获取UDP收发所用网卡的链路速率等信息
在Qt中通过QUdpSocket获取UDP收发网卡的链路速率方案
核心结论
可以直接通过QUdpSocket实现需求,不需要必须使用底层WinSock套接字,Qt的上层接口足够获取收发UDP时使用的本地IP,结合Windows的GetAdaptersAddresses接口即可拿到链路速率。
具体实现步骤
1. 获取UDP收发对应的本地IP地址
根据QUdpSocket的绑定方式,分两种情况处理:
情况A:套接字绑定了特定网卡IP
如果你的QUdpSocket是显式绑定到某块网卡的IP(比如bind(QHostAddress("192.168.1.100"), 1234)),直接调用localAddress()即可获取该IP:
QUdpSocket udpSocket; udpSocket.bind(QHostAddress("192.168.1.100"), 1234); QHostAddress localIp = udpSocket.localAddress();
情况B:套接字绑定到任意地址(自动选网卡)
如果套接字绑定的是QHostAddress::AnyIPv4或AnyIPv6,可以通过以下方式确定实际用于收发的本地IP:
- 发送数据时:创建临时QUdpSocket并建立逻辑连接到目标地址,获取本地IP:
QHostAddress targetIp("192.168.1.200"); quint16 targetPort = 5678; QUdpSocket tempSocket; tempSocket.connectToHost(targetIp, targetPort); QHostAddress localIp = tempSocket.localAddress(); tempSocket.disconnectFromHost();
- 接收数据时:收到第一个数据包后,直接通过当前套接字的
localAddress()获取实际接收的网卡IP(Qt会自动填充该值)。
2. 通过GetAdaptersAddresses获取链路速率
拿到本地IP后,调用Windows的GetAdaptersAddresses接口遍历网卡适配器列表,匹配对应的IP地址,从IP_ADAPTER_ADDRESSES结构体的LinkSpeed字段获取链路速率(单位为bps):
- 千兆网卡对应
LinkSpeed = 1000000000(1Gbps) - 百兆网卡对应
LinkSpeed = 100000000(100Mbps)
核心逻辑伪代码:
IP_ADAPTER_ADDRESSES* pAddresses = nullptr; ULONG outBufLen = 0; // 先获取所需缓冲区大小 GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, nullptr, &outBufLen); pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen); if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAddresses, &outBufLen) == ERROR_SUCCESS) { IP_ADAPTER_ADDRESSES* pCurrAddr = pAddresses; while (pCurrAddr != nullptr) { // 遍历当前网卡的所有IP地址 IP_ADAPTER_UNICAST_ADDRESS* pUnicast = pCurrAddr->FirstUnicastAddress; while (pUnicast != nullptr) { sockaddr_in* pIpv4 = reinterpret_cast<sockaddr_in*>(pUnicast->Address.lpSockaddr); QString ipStr = QString::fromUtf8(inet_ntoa(pIpv4->sin_addr)); if (ipStr == localIp.toString()) { // 找到匹配的网卡,获取链路速率 ULONG linkSpeed = pCurrAddr->LinkSpeed; qDebug() << "链路速率:" << linkSpeed / 1000000 << "Mbps"; goto cleanup; } pUnicast = pUnicast->Next; } pCurrAddr = pCurrAddr->Next; } } cleanup: free(pAddresses);
关键注意事项
- 确保处理IPv4和IPv6地址的兼容性,
GetAdaptersAddresses的第一个参数可指定AF_INET或AF_INET6来筛选对应地址族。 GetAdaptersAddresses不需要管理员权限即可获取基本网卡信息,包括链路速率。- 如果需要实时监控链路速率变化,可定期调用该接口更新数据。
内容的提问来源于stack exchange,提问作者il_mix
相关产品推荐
相关产品推荐

