QT 网络编程之主机信息查询(QHostInfo 和 QNetworkInterface类)简介

Qt 网络模块提供了用于编写 TCP/IP 客户端和服务器端程序的各种类,如用于 TCP 通信的QTcpSocket 和 QTcpServer,用于 UDP 通信的 QUdpSocket,还有用于实现 HTTP、FTP 等普通网络协议的高级类如 QNetworkRequest,QNetworkReply 和QNetworkAccessManager。Qt 网络模块还提供用于网络代理、网络承载管理的类,提供基于安全套接字层(Secure Sockets Layer,SSL)协议的安全网络通信的类。

要在程序中使用 Qt 网络模块,需要在项目配置文件中增加一条配置语句:
Qt += network

1、QHostInfo 和 QNetworkInterface 类

查询一个主机的MAC地址或IP 地址是网络应用程序中经常用到的功能,Qt提供了QHostInfo和QNetworkInterface 类可以用于此类信息的查询。

QHostInfo 的静态函数 localHostName()可获取本机的主机名,静态函数 fromName()可以通过主机名获取IP 地址,静态函数 lookupHost()可以通过一个主机名,以异步方式查找这个主机的IP地址。下表是QHostInfo 类主要的功能函数(省略了函数中的const 关键字)。

类别

函数原型

作用

公共函数

QList<QHostAddress> addresses()

HostInfoError error()

QString errorString()

QString hostName()

int lookupld()

返回与 hostname()主机关联的IP 地址列表

如果主机查找失败,返回失败类型

如果主机查找失败,返回错误描述字符串

返回通过 IP查找的主机的名称

返回本次查找的ID

静态函数

void abortHostLookup(int id)

QHostInfo fromName(QString &name)

QString localDomainName()

QString localHostName()

int lookupHost(QString&name,

QObiect*receiver,char *member)

中断主机查找

返回指定的主机名的IP 地址

返回本机DNS域名

返回本机主机名

以异步方式根据主机名查找主机的 IP 地址,并返回一个表示本次查找的ID,可用于 abortHostLookup()

QNetworkInterface 可以获得运行应用程序的主机的所有 IP 地址和网络接口列表。静态函数allInterfaces()返回主机上所有的网络接口的列表,一个网络接口可能包括多个的IP 地址,每个IP地址与掩码或广播地址关联。如果无需知道子网掩码和广播的IP 地址,使用静态函数 allAddresses()可以获得主机上的所有IP 地址列表。下表是QNetworkInterface 类的主要功能函数。

类别

函数原型

作用

公共函数

QList<QNetworkAddressEntry> addressEntries()

OString hardwareAddress()

QString humanReadableName()

bool isValid()

QString name()

返回该网络接口(包括子网掩码和广播地址)的IP 地址列表

返回该接口的低级硬件地址,以太网里就是 MAC 地址

返回可以读懂的接口名称,如果名称不确定,得到的就是name()函数的返回值

如果接口信息有效就返回 true

返回网络接口名称

静态函数

QList<QHostAddress> allAddresses()

QList<QNetworkInterface> allInterfaces()

返回主机上所有 IP 地址的列表

返回主机上所有接口的网络列表

为演示这两个类的主要功能,创建一个窗口基于 QDialog 的应用程序实例运行时界面如下图所示。对话框界面由 UI设计器设计,主要代码都是各按钮的 clicked()信号的槽函数。

窗口上的“QHostInf 取本机主机名和I地址”按的响应代码如下:

void HostDialog::on_btnGetHostInfo_clicked()
{
    QString hostName = QHostInfo::localHostName();
    ui->textInfo->appendPlainText(("本机主机名称:") + hostName + "\n" );
    QHostInfo hostInfo = QHostInfo::fromName(hostName);
    QList<QHostAddress> addList = hostInfo.addresses();
    if(addList.isEmpty())
    {
        return;
    }
    for(int i = 0; i < addList.count(); i++)
    {
        QHostAddress host = addList.at(i);
        bool show = ui->chkOnlyIPv4->isChecked();
        if(show)
        {
            show = (QAbstractSocket::IPv4Protocol == host.protocol());
        }
        else{
            show = true;
        }
        if(show)
        {
            ui->textInfo->appendPlainText("协议:" + protocolName(host.protocol()));
            ui->textInfo->appendPlainText("本机IP地址:" + host.toString());
            ui->textInfo->appendPlainText("");
        }

    }
}

 查找主机地址信息

QHostInfo 的静态函数 lokupHost()可以根据主机名、域名或 IP 地址查找主机的地址信息lookupHost()函数原型如下:
int QHostInfo::lookupHost(const QString &name, QObject *receiver, const char *member)

输入参数 name 是表示主机名的字符串,可以是一个主机名、一个域名,或者是一个IP 地址lookupHost()以异步方式查找主机地址,参数 receiver 和 member 指定一个响应槽函数的接收者和槽函数名称。执行 lookupHost()后,程序可能需要花一定时间来查找主机地址,但不会阻塞程序的运行。当查找到主机地址后,通过信号通知设定的槽函数,在槽函数里读取查找的结果。函数返回一个表示查找的ID。
窗口“OHostInfo 查找域名的IP 地址”按的槽函数及 lokupHost()函数关联槽函数代码如下:

void HostDialog::on_btnLookup_clicked()
{
    QString hostname = ui->lineEdit->text();
    ui->textInfo->appendPlainText("正在查找主机信息:" + hostname);
    QHostInfo::lookupHost(hostname, this, SLOT(lookedUpHostInfo(QHostInfo)));
}

void HostDialog::lookedUpHostInfo(const QHostInfo &host)
{
    QList<QHostAddress> addList = host.addresses();
    if(addList.isEmpty())
    {
        return;
    }
    for(int i = 0; i < addList.count(); i++)
    {
        QHostAddress aHost = addList.at(i);
        bool show = ui->chkOnlyIPv4->isChecked();
        if(show)
        {
            show = QAbstractSocket::IPv4Protocol == aHost.protocol();
        }
        else{
            show = true;
        }
        if(show)
        {
            ui->textInfo->appendPlainText("协议:" + protocolName(aHost.protocol()));
            ui->textInfo->appendPlainText(aHost.toString());
        }
    }
}

QNetworkInterface 可以获得应用程序所在主机的所有网络接口,包括其子网码和广播地址等静态函数QNetworkInterface::allInterfaces()获取所有网络接口的列表,函数原型为:

QList<QNetworkInterface> QNetworkInterface::allInterfaces()

其返回结果是一个QNetworkInterface 类的列表。界面上“QNetworkInterface::allInterfaces()”按钮的响应代码如下:

void HostDialog::on_btnAllInterfaces_clicked()
{
    QList<QNetworkInterface> list = QNetworkInterface::allInterfaces();
    for(int i = 0; i < list.count(); i++)
    {
        QNetworkInterface interface = list.at(i);
        if(!interface.isValid())
        {
            continue;
        }
        ui->textInfo->appendPlainText("设备名称:" + interface.humanReadableName());
        ui->textInfo->appendPlainText("硬件地址:" + interface.hardwareAddress());
        QList<QNetworkAddressEntry> entryList = interface.addressEntries();
        for(int j = 0; j < entryList.count(); j++)
        {
            QNetworkAddressEntry entry = entryList.at(j);
            ui->textInfo->appendPlainText("IP 地址:" + entry.ip().toString());
            ui->textInfo->appendPlainText("子网掩码:" + entry.netmask().toString());
            ui->textInfo->appendPlainText("广播地址:" + entry.broadcast().toString() + "\n");
            ui->textInfo->appendPlainText("\n");
        }
    }
}

通过QNetworkInterface::allInterfaces()获取网络接口列表 list之后,显示每个接口的humanReadableName()和 hardwareAddress()。每个接口又有一个 QNetworkAddressEntry 类型的地址列表,通过addressEntries()获得这个列表。

QNetworkAddressEntry 包含了一个网络接口的IP 地址、子网掩码和广播地址,分别用ip(),netmask()和 broadcast()函数返回。

QNetworkInterface::allInterfaces()返回的网络接口的信息很多,如果无需知道子网掩码和广播地址等信息,可以使用QNetworkInterface::allAddresses()只获取IP 地址界面上“QNetworkInterface ::allAddresses()”按钮的响应代码如下:

void HostDialog::on_btnAllAddressed_clicked()
{
    QList<QHostAddress> addList = QNetworkInterface::allAddresses();
    if(addList.isEmpty())
    {
        return;
    }
    for(int i = 0; i < addList.count(); i++)
    {
        QHostAddress info = addList.at(i);
        bool show = ui->chkOnlyIPv4->isChecked();
        if(show)
        {
            show = QAbstractSocket::IPv4Protocol == info.protocol();
        }
        else
        {
            show = true;
        }
        if(show)
        {
            ui->textInfo->appendPlainText("协议:" + protocolName(info.protocol()));
            ui->textInfo->appendPlainText("IP地址:" + info.toString());
            ui->textInfo->appendPlainText("");
        }
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木士易

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值