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++开发指南

相关推荐
ProcessOn官方账号27 分钟前
如何绘制网络拓扑图?附详细分类解说和用户案例!
网络·职场和发展·流程图·拓扑学
Ven%1 小时前
如何在防火墙上指定ip访问服务器上任何端口呢
linux·服务器·网络·深度学习·tcp/ip
神的孩子都在歌唱1 小时前
TCP/IP 模型中,网络层对 IP 地址的分配与路由选择
网络·tcp/ip·智能路由器
阿雄不会写代码1 小时前
ubuntu安装nginx
linux·服务器·网络
starstarzz2 小时前
计算机网络实验四:Cisco交换机配置VLAN
网络·计算机网络·智能路由器·vlan·虚拟局域网
网安墨雨3 小时前
常用网络协议
网络·网络协议
Tlzns3 小时前
Linux网络——UDP的运用
linux·网络·udp
矛取矛求4 小时前
QT的前景与互联网岗位发展
开发语言·qt
Leventure_轩先生4 小时前
[WASAPI]从Qt MultipleMedia来看WASAPI
开发语言·qt
黑客老陈4 小时前
新手小白如何挖掘cnvd通用漏洞之存储xss漏洞(利用xss钓鱼)
运维·服务器·前端·网络·安全·web3·xss