QHostInfo提供了一个静态函数,允许您自己通过使用主机名执行此类查找。
QHostInfo
在建立网络连接之前,QTcpSocket和QUdpSocket执行一个名称查找,将所连接的主机名转换为一个IP地址。此操作通常使用DNS(域名服务)协议执行。
QHostInfo提供了一个静态函数,允许您自己执行此类查找。通过使用主机名、QObject指针和槽签名调用QHostInfo::lookupHost(), QHostInfo将执行名称查找,并在结果准备好时调用给定槽。实际的查找是在单独的线程中完成的,使用操作系统自己的方法来执行名称查找。
QHostInfo还提供了一个名为QHostInfo::fromName()的静态函数,它接受主机名作为参数并返回结果。在这种情况下,名称查找在与调用者相同的线程中执行。此重载对于非gui应用程序或在单独的非gui线程中进行名称查找非常有用。(在GUI线程中调用此函数可能会导致用户界面冻结,而函数在执行查找时阻塞。)
QNetworkInterface
QNetworkInterface表示连接到运行程序的主机的一个网络接口。每个网络接口可以包含零个或多个IP地址,每个IP地址可选地与一个网络掩码和/或一个广播地址相关联。可以通过addressEntries()获得这类三元组的列表。另外,当不需要网掩码或广播地址或其他信息时,使用alladdress()便利函数只获取活动接口的IP地址。
QNetworkInterface还使用hardwareAddress()报告接口的硬件地址。
并非所有操作系统都支持报告所有特性。在所有平台中,只有IPv4地址被这个类保证列出。特别地,IPv6地址列表只支持Windows, Linux, macOS和BSDs。
实践案例
catnetwork.h
#ifndef CATNETWORK_H
#define CATNETWORK_H
#include <QObject>
class QHostInfo;
class CatNetWork : public QObject
{
Q_OBJECT
Q_ENUMS(IP)
public:
explicit CatNetWork(QObject *parent = nullptr);
~CatNetWork();
public:
enum IP {
V4,
V6
};
void lookupHost(QString host);
// 获取当前系统 所有可用的Ipv4地址
QList<QString> GetAllIpaddressIpv4( void ) const;
// 获取当前系统 所有可用的Ipv6地址
QList<QString> GetAllIpaddressIpv6( void ) const;
// 获取当前系统 所有可用的网络设备名
QList<QString> GetAllNetWorkName( void ) const;
// 根据 网络设备名获取MAC地址
QString GetNetWorkHardware(QString name);
// 根据 IP获取MAC地址
QString GetNetWorkHardware(QString ipaddress, IP ip);
// 根据 IP获取广播地址
QString GetNetWorkBroadcast(QString ipaddress, IP ip);
// 根据 IP获取网络掩码
QString GetNetWorkNetMask(QString ipaddress, IP ip);
private:
struct NETWORKADDRESSENTRY {
QString IpAddressV4;
QString IpAddressV6;
QString NetMask;
QString Broadcast;
};
struct NETWORKINTERFACE {
QString Name;
QString Hardware;
QList<NETWORKADDRESSENTRY> Entry;
};
void InitNetworkInterface( void );
signals:
void LookupHost(QString host);
void update_NetWorkIpv4(QList<QString>);
void update_NetWorkIpv6(QList<QString>);
private slots:
void Update_NetworkInterface( void );
//void lookedUp(const QHostInfo &host);
private:
QList<NETWORKINTERFACE> m_lNetworkimterface;
QList<QString> m_lIpaddressIpv4;
QList<QString> m_lIpaddressIpv6;
QList<QString> m_lName;
};
#endif // CATNETWORK_H
catnetwork.cpp
#include "catnetwork.h"
#include <QHostInfo>
#include <QNetworkInterface>
CatNetWork::CatNetWork(QObject *parent)
: QObject(parent)
{
Update_NetworkInterface();
}
CatNetWork::~CatNetWork()
{
}
void CatNetWork::lookupHost(QString host)
{
QHostInfo::lookupHost(host, this, [=](const QHostInfo &host){
if(host.error() != QHostInfo::NoError)
{
emit LookupHost(host.errorString());
}
foreach(const QHostAddress &address, host.addresses())
{
emit LookupHost(address.toString());
}
});
}
QList<QString> CatNetWork::GetAllIpaddressIpv4() const
{
return m_lIpaddressIpv4;
}
QList<QString> CatNetWork::GetAllIpaddressIpv6() const
{
return m_lIpaddressIpv6;
}
QList<QString> CatNetWork::GetAllNetWorkName() const
{
return m_lName;
}
QString CatNetWork::GetNetWorkHardware(QString name)
{
QString hardware = "";
for(auto temp : m_lNetworkimterface)
{
if(temp.Name == name)
{
hardware = temp.Hardware;
}
}
return hardware;
}
QString CatNetWork::GetNetWorkHardware(QString ipaddress, CatNetWork::IP ip)
{
QString hardware = "";
for(auto temp : m_lNetworkimterface)
{
for(auto tempentry : temp.Entry)
{
if(ip == CatNetWork::IP::V4 && ipaddress == tempentry.IpAddressV4)
{
hardware = temp.Hardware;
} else if(ip == CatNetWork::IP::V6 && ipaddress == tempentry.IpAddressV6)
{
hardware = temp.Hardware;
}
}
}
return hardware;
}
QString CatNetWork::GetNetWorkBroadcast(QString ipaddress, CatNetWork::IP ip)
{
QString broadcast = "";
for(auto temp : m_lNetworkimterface)
{
for(auto tempentry : temp.Entry)
{
if(ip == CatNetWork::IP::V4 && ipaddress == tempentry.IpAddressV4)
{
broadcast = tempentry.Broadcast;
} else if(ip == CatNetWork::IP::V6 && ipaddress == tempentry.IpAddressV6)
{
broadcast = tempentry.Broadcast;
}
}
}
return broadcast;
}
QString CatNetWork::GetNetWorkNetMask(QString ipaddress, CatNetWork::IP ip)
{
QString netmask = "";
for(auto temp : m_lNetworkimterface)
{
for(auto tempentry : temp.Entry)
{
if(ip == CatNetWork::IP::V4 && ipaddress == tempentry.IpAddressV4)
{
netmask = tempentry.NetMask;
} else if(ip == CatNetWork::IP::V6 && ipaddress == tempentry.IpAddressV6)
{
netmask = tempentry.NetMask;
}
}
}
return netmask;
}
void CatNetWork::InitNetworkInterface()
{
// 获取所有网络接口的列表
QList<QNetworkInterface> list = QNetworkInterface::allInterfaces();
// 遍历每一个网络接口
foreach(QNetworkInterface interface, list)
{
NETWORKINTERFACE temp;
// 接口名
temp.Name = interface.name();
m_lName.push_back(temp.Name);
// 硬件地址
temp.Hardware = interface.hardwareAddress();
// 获取IP地址条目列表,每个条目包含一个IP地址,子网掩码和广播地址
QList<QNetworkAddressEntry> entryList = interface.addressEntries();
foreach(QNetworkAddressEntry entry, entryList)
{
NETWORKADDRESSENTRY EntryTemp;
// IP 地址
QString ip = entry.ip().toString();
if(!ip.isEmpty())
{
if(entry.ip().protocol() == QAbstractSocket::IPv4Protocol)
{
EntryTemp.IpAddressV6 = "";
EntryTemp.IpAddressV4 = ip;
m_lIpaddressIpv4.push_back(EntryTemp.IpAddressV4);
} else if(entry.ip().protocol() == QAbstractSocket::IPv6Protocol) {
EntryTemp.IpAddressV4 = "";
EntryTemp.IpAddressV6 = ip;
m_lIpaddressIpv6.push_back(EntryTemp.IpAddressV6);
}
}
// 子网掩码
EntryTemp.NetMask = entry.netmask().toString();
// 广播地址
EntryTemp.Broadcast = entry.broadcast().toString();
temp.Entry.push_back(EntryTemp);
}
m_lNetworkimterface.push_back(temp);
}
}
void CatNetWork::Update_NetworkInterface()
{
m_lNetworkimterface.clear();
m_lName.clear();
m_lIpaddressIpv4.clear();
m_lIpaddressIpv6.clear();
InitNetworkInterface();
emit update_NetWorkIpv4(m_lIpaddressIpv4);
emit update_NetWorkIpv6(m_lIpaddressIpv6);
}
main.cpp
#include <QCoreApplication>
#include <QtNetwork>
#include <QHostInfo>
#include <QDebug>
#include "catnetwork.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
CatNetWork network;
QObject::connect(&network, &CatNetWork::LookupHost, &network, [=](QString host){
qDebug() << "Host: " << host;
});
QObject::connect(&network, &CatNetWork::update_NetWorkIpv4, &network, [=](QList<QString> list){
qDebug() << "Ipv4: " << list;
});
QObject::connect(&network, &CatNetWork::update_NetWorkIpv6, &network, [=](QList<QString> list){
qDebug() << "Ipv6: " << list;
});
network.lookupHost("www.graycatya.com");
qDebug() << network.GetNetWorkHardware(network.GetAllIpaddressIpv4()[1], CatNetWork::V4);
qDebug() << network.GetNetWorkBroadcast(network.GetAllIpaddressIpv4()[1], CatNetWork::V4);
qDebug() << network.GetNetWorkNetMask(network.GetAllIpaddressIpv4()[1], CatNetWork::V4);
network.Update_NetworkInterface();
return a.exec();
}