QT网络(一):主机信息查询

网络简介

在QT中进行网络通信可以使用QT提供的Qt Network模块,该模块提供了用于编写TCP/IP网络应用程序的各种类,如用于TCP通信的QTcpSocket和 QTcpServer,用于 UDP 通信的 QUdpSocket,还有用于网络承载管理的类,以及基于 SSL 协议的用于网络安全通信的类。

要使用该模块,需要在项目配置文件(.pro)中添加如下配置语句:

cpp 复制代码
QT += network

使用 QHostInfo 类和 QNetworkInterface 类可以获取主机的一些网络信息,如 IP 地址和 MAC 地址,这是网络通信应用需要获取的基本信息。

QHostInfo 类

可以根据主机名获取主机的 IP 地址,或者通过 IP 地址获取主机名。

该类的主要接口函数如下表:

QHostInfo 类的静态函数 localHostName()可获取本机的主机名,静态函数 fromName()可以通过主机名获取 IP地址,静态函数 lookupHost()可以通过一个主机名以异步方式查找这个主机的 IP 地址。

QNetworkInterfac 类

可以获得运行程序的主机的所有 IP 地址和网络接口列表。

该类的主要接口函数如下表:

静态函数 allInterfaces()返回主机上所有的网络接口列表,一个网络接口可能包含多个 IP 地址,每个 IP 地址与掩码或广播地址关联。如果无须知道子网掩码和广播地址,使用静态函数allAddresses()可以获得主机上所有 IP 地址的列表。

示例程序解读

显示本机地址信息

使用QHostInfo 类

cpp 复制代码
void MainWindow::on_btnGetHostInfo_clicked()
{//"获取本机主机名和IP地址" 按钮
    ui->textEdit->clear();
    QString hostName=QHostInfo::localHostName();    //本地主机名
    ui->textEdit->appendPlainText("本机主机名:"+hostName+"\n");

    QHostInfo   hostInfo=QHostInfo::fromName(hostName);  //本机IP地址
    QList<QHostAddress> addrList=hostInfo.addresses();    //IP地址列表
    if (addrList.isEmpty())
        return;

    foreach (QHostAddress host, addrList)
    {
        bool show=ui->chkBox_OnlyIPv4->isChecked();   //只显示IPv4
        show= show? (host.protocol()==QAbstractSocket::IPv4Protocol):true;
        if (show)
        {
            ui->textEdit->appendPlainText("协 议:"+protocolName(host.protocol())); //协议类型
            ui->textEdit->appendPlainText("本机IP地址:"+host.toString());           //IP地址
            ui->textEdit->appendPlainText(QString("isGlobal()=%1\n").arg(host.isGlobal()));
//            ui->textEdit->appendPlainText(QString("isBroadcast()=%1").arg(host.isBroadcast()));
//            ui->textEdit->appendPlainText(QString("isLoopback()=%1").arg(host.isLoopback()));
//            ui->textEdit->appendPlainText(QString("isMulticast()=%1\n").arg(host.isMulticast()));
        }
    }
}

QString MainWindow::protocolName(QAbstractSocket::NetworkLayerProtocol protocol)
{//通过协议类型返回协议名称
    switch(protocol)
    {
    case QAbstractSocket::IPv4Protocol:
        return "IPv4";
    case QAbstractSocket::IPv6Protocol:
        return "IPv6";
    case QAbstractSocket::AnyIPProtocol:
        return "Any Internet Protocol";
    default:
        return "Unknown Network Layer Protocol";
    }
}

1、通过静态函数QHostInfo::localHostName()获取本机主机名 hostName,然后使用静态函数 QHostInfo::fromName(hostName)获取主机的信息 hostInfo。

2、通过hostInfo.addresses()可以获取到主机的ip地址列表,有无线局域网WLAN、以太网,如果安装了虚拟机配置了相关地址,还会出现一些名如VMnetx的网络地址(NAT或桥接)。

在cmd中运行ipconfig命令得到的结果如下所示:

3、addrList 是 QHostAddress 类型的列表,提供 IP 地址的信息,包括 IPv4 地址和 IPv6 地址,可以通过QHostAddress::protocol()函数来获取IP地址的类型。

使用QNetworkInterface 类

该类也可以实现应用程序所在主机的所有网络接口的信息,包括子网掩码和广播地址。可以使用静态函数 QNetworkInterface::allAddresses()获取 IP 地址:

cpp 复制代码
void MainWindow::on_btnAllAddress_clicked()
{//"allAddresses()"按钮
    ui->textEdit->clear();
    QList<QHostAddress> addrList=QNetworkInterface::allAddresses();
    if (addrList.isEmpty())
        return;
    foreach (QHostAddress host, addrList)
    {
        bool show=ui->chkBox_OnlyIPv4->isChecked();//只显示IPv4
        show= show? (host.protocol()==QAbstractSocket::IPv4Protocol):true;
        if (show)
        {
            ui->textEdit->appendPlainText("协  议:"+protocolName(host.protocol()));
            ui->textEdit->appendPlainText("IP地址:"+host.toString());
            ui->textEdit->appendPlainText(QString("isGlobal()=%1\n").arg(host.isGlobal()));
        }
    }
}

QNetworkInterface::allAddresses()的功能与 QHostInfo::addresses()的功能相似,都是返回一个

QHostAddress 类型的列表。区别是:QNetworkInterface 会返回更多地址,包括表示本机的 IP 地址127.0.0.1,而 QHostInfo 不会返回这个 IP 地址。

如果想要获取更多的信息,如子网掩码和广播地址等信息等,可以使用静态函数 allInterfaces()获取所有网络接口的列表:

cpp 复制代码
void MainWindow::on_btnAllInterface_clicked()
{//"allInterfaces()"按钮
    ui->textEdit->clear();
    QList<QNetworkInterface> list=QNetworkInterface::allInterfaces();   //网络接口列表
    foreach(QNetworkInterface interface,list)
    {
        if (!interface.isValid())
           continue;

        ui->textEdit->appendPlainText("设备名称:"+interface.humanReadableName());
        ui->textEdit->appendPlainText("硬件地址:"+interface.hardwareAddress());
        ui->textEdit->appendPlainText("接口类型:"+interfaceType(interface.type()));
        QList<QNetworkAddressEntry> entryList=interface.addressEntries();   //地址列表
        foreach(QNetworkAddressEntry entry, entryList)
        {
            ui->textEdit->appendPlainText("   IP 地址:"+entry.ip().toString());
            ui->textEdit->appendPlainText("   子网掩码:"+entry.netmask().toString());
            ui->textEdit->appendPlainText("   广播地址:"+entry.broadcast().toString()+"\n");
        }
    }
}

QString MainWindow::interfaceType(QNetworkInterface::InterfaceType type)
{//根据枚举值返回字符串
    switch(type)
    {
    case QNetworkInterface::Unknown:
        return "Unknown";
    case QNetworkInterface::Loopback:
        return "Loopback";
    case QNetworkInterface::Ethernet:
        return "Ethernet";
    case QNetworkInterface::Wifi:
        return "Wifi";
    default:
        return "Other type";
    }
}

每个接口包含设备名称、硬件地 址和接口类型。每个接口有一个 QNetworkAddressEntry 类型的地址列表,通过函数 addressEntries()可获得这个列表。QNetworkAddressEntry 类包含网络接口的 IP 地址、子网掩码和广播地址,可分别用 ip()、netmask()和 broadcast()函数获取。

该示例显示的内容与在cmd使用ipconfig得到的结果大致相同。

查找主机地址信息

QHostInfo 的静态函数 lookupHost()可以根据主机名查找主机的地址信息。原型如下:

int QHostInfo::lookupHost(const QString &name, QObject *receiver, const char *member)

参数 name 是表示主机名的字符串,可以是主机名、域名或 IP 地址。参数 receiver 和 member 指定接收者和槽函数名称。

注意:该函数以异步方式查找主机地址,运行 lookupHost()函数后,程序可能需要花一定时间来查找主机地址,但运行该函数不会阻塞程序的运行。当查找到主机地址后,通过发射信号通知设定的槽函数,在槽函数里读取查找的结果。

cpp 复制代码
void MainWindow::on_btnLookup_clicked()
{//"查找域名的IP地址" 按钮
    ui->textEdit->clear();
    QString hostname=ui->comboBox->currentText();     //读取主机名
    ui->textEdit->appendPlainText("正在查找查找主机信息:"+hostname);
    QHostInfo::lookupHost(hostname,this,SLOT(do_lookedUpHostInfo(QHostInfo)));
}

void MainWindow::do_lookedUpHostInfo(const QHostInfo &host)
{//查找主机信息的槽函数
    QList<QHostAddress> addrList=host.addresses();   //获取主机的地址列表
    if (addrList.isEmpty())
        return;
    foreach(QHostAddress host, addrList)
    {
        bool show=ui->chkBox_OnlyIPv4->isChecked();   //只显示IPv4
        show= show? (host.protocol()==QAbstractSocket::IPv4Protocol):true;
        if (show)
        {
            ui->textEdit->appendPlainText("协 议:"+protocolName(host.protocol()));
            ui->textEdit->appendPlainText(host.toString());
            ui->textEdit->appendPlainText(QString("isGlobal()=%1\n").arg(host.isGlobal()));
        }
    }
}

如上代码中,当通过lookupHost()查询到主机后,会将查询到的QHostInfo类型变量通过信号传递到槽函数中,和上一步骤一样,通过addresses()获取到IP地址列表后打印输出。

参考

QT6 C++开发指南

相关推荐
用户805533698034 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner4 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz9 天前
QML Hello World 入门示例
qt
xcyxiner12 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner13 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner13 天前
DicomViewer (添加模型类)3
qt
xcyxiner14 天前
DicomViewer (目录调整) 2
qt
xcyxiner14 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
网络研究院16 天前
2026年网络安全
网络·安全·法律·法规·趋势·发展
酣大智16 天前
ARP代理--工作原理
运维·网络·arp·arp代理