Qt-获取主机网络信息

11 篇文章 12 订阅


简述:

Qt 中提供了几个用于获取主机网络信息的类,包括QHostInfoQHostAddressQNetworkInterface以及QNetworkAddressEntry

通过这几个类获得本机的主机名IP地址硬件地址等网络信息。


QHostInfo 类:查询与特定主机名相关联的主机的IP地址,或者与一个IP地址相关联的主机名

QHostAddress 类:提供一个IP地址,可提供独立于平台和协议的方式来保存 IPv4IPv6 地址。

QNetworkInterface 类:负责提供主机IP地址和网络接口的列表,表示了当前程序正在运行时与主机绑定的一个网络接口。

QNetworkAddressEntry 类:存储了一个网络接口所支持的一个IP地址,同时还有与之相关的子网掩码广播地址


系统:Windows 7

Qt 环境: qt-opensource-windows-x86-mingw530-5.7.0.exe



1、 样例

1 > 修改工程文件 .pro 


本机网络信息是属于网络模块。获取本机网络信息,那就要使用Qt 提供的网络模块 QtNetwork,即在工程文件 .pro 中加入:


QT       += network

2 >  #include  头文件 .h


只需要 #include 两个头文件即可


#include <QHostInfo>
#include <QNetworkInterface>

3 > 范例


void NetworkInformation::getHostInformation()
{

    /***********************************************************/
    //QHostInfo 提供一系列有关网络信息的静态函数,可获取主机名、IP地址
    QString localHostName = QHostInfo::localHostName();         // 获取本机主机名
    qDebug() << "主机名: " << localHostName;
    qDebug() << endl;

    /***********************************************************/
    //根据主机名获取相关主机信息,包括IP地址。
    QHostInfo hostInfo = QHostInfo::fromName(localHostName);
    QList<QHostAddress> addrList = hostInfo.addresses();        // 获取本主机上的IP地址列表
    qDebug() << "本主机上的IP地址列表,总计: " << addrList.count() ;

    /***********************************************************/
    foreach (QHostAddress var, addrList) {
        qDebug() << var.toString(); //本机IP地址列表
    }
    qDebug() << endl;

    /***********************************************************/
    if(!addrList.isEmpty()) //获得的主机IP地址列表可能为空。
    {
        // 在不为空情况下使用第一个IP地址,可能IPv6,也可能IPv4
        qDebug() << "first ip addr:" << addrList.first().toString();
    }
    qDebug() << endl;

    /***********************************************************/
    QString ipAddress;
    //QList<QHostAddress> addrList = QNetworkInterface::allAddresses(); //仅仅获取IP地址列表
    for (int i = 0; i < addrList.size(); ++i) {
        if (addrList.at(i) != QHostAddress::LocalHost &&
            addrList.at(i).toIPv4Address()) { //是IPv4地址且非 QHostAddress::LocalHost
            ipAddress = addrList.at(i).toString();
            qDebug() << "first ipv4 addr:" << ipAddress;// 在不为空情况下使用第一个IPv4地址
            break;
        }
    }
    qDebug() << endl;

    /***********************************************************/
    // 获取本机的网络接口列表
    QList<QNetworkInterface> ifaceList = QNetworkInterface::allInterfaces();
    for (int i = 0; i < ifaceList.count(); i++){
        QNetworkInterface var = ifaceList.at(i);
        qDebug() << tr("########## 设备%1 ############").arg(i);
        qDebug() << tr("接口名称:") << var.humanReadableName();
        qDebug() << tr("设备名称:") << var.name();
        qDebug() << tr("硬件地址:") << var.hardwareAddress();

        /***********************************************************/
        // 读取一个IP地址的关联信息列表
        QList<QNetworkAddressEntry> entryList = var.addressEntries();
        //qDebug() << "IP地址的关联信息列表: ";
        //foreach(QNetworkAddressEntry entry, entryList){
            //qDebug() << "IP: " << entry.ip().toString();
            //qDebug() << "子网掩码:" << entry.netmask().toString();
            //qDebug() << "广播地址:" << entry.broadcast().toString();
        //}

        /***********************************************************/
        // 读取一个IPv4地址的关联信息列表
        //qDebug() << "IPv4地址的关联信息列表: ";
        foreach(QNetworkAddressEntry ipv4entry, entryList){
            if (ipv4entry.ip().toIPv4Address())
            {
                qDebug() << "IP: " << ipv4entry.ip().toString();
                qDebug() << "子网掩码:" << ipv4entry.netmask().toString();
                qDebug() << "广播地址:" << ipv4entry.broadcast().toString();
            }

        }
    }

    /***********************************************************/
}



输出:





2、 QHostInfo 详解


1 > QHostInfo类 :查询与特定主机名相关联的主机的IP地址,或者与一个IP地址相关联的主机名


2 > 有两种查询方式:


A.  异步方式,找到主机就发射信号。

此方式调用的 lookupHost() ,此函数有3个参数,分别是主机名或IP地址接收对象接收槽函数,并且返回一个查询ID

若要中止查询,则可调用abortHostLookup() 函数,参数是查询ID


    static int lookupHost(const QString &name, QObject *receiver, const char *member);//异步方式查询
    static void abortHostLookup(int lookupId); //中止查询


若查询成功,则调用接收槽函数。查询结果被存储到 QHostInfo对象中;可使用以下方式查看查询结果:

    QString hostName() const; //获取查询的主机名
    QList<QHostAddress> addresses() const; //获取主机的IP地址列表
    HostInfoError error() const;  //返回错误的类型
    QString errorString() const;  //返回查询错误描述


例如:


NetworkInformation::NetworkInformation(QWidget *parent)
    : QWidget(parent)
{
     QHostInfo::lookupHost("www.baidu.com",
                           this, SLOT(printResult(QHostInfo)));
 }
 void NetworkInformation::printResult(QHostInfo result)
 {
     qDebug() << result.hostName(); //获取查询的主机名
     QList<QHostAddress> addrList = result.addresses(); //获取主机的IP地址列表
     if (!addrList.isEmpty())
     {
         for  (int i = 0; i < addrList.size(); i++)
         {
             qDebug() << addrList.at(i);
         }
     }
 }


QHostInfo::HostInfoError
常量描述
QHostInfo::NoError0查找成功
QHostInfo::HostNotFound 1没有发现主机对应的IP地址
QHostInfo::UnknownError2未知错误


B.  阻塞方式,调用的是 QHostInfo::fromName() 函数,查询给定主机名对应的IP地址。

此函数查询期间将阻塞,这意味着程序执行期间将挂起直到返回查询结果。

返回的查询结果存储在 QHostInfo 对象中。


    static QHostInfo fromName(const QString &name); //阻塞方式查询

例如:


NetworkInformation::NetworkInformation(QWidget *parent)
    : QWidget(parent)
 {
     QHostInfo info = QHostInfo::fromName("www.baidu.com"); //阻塞方式查询
     qDebug() << info.addresses();
 }



3、 QHostAddress 详解


1 > QHostAddress 类:提供一个IP地址,可提供独立于平台和协议的方式来保存 IPv4 和 IPv6 地址,故可用于地址过滤。

QHostAddress 通常与QTcpSocket、QTcpServer、QUdpSocket 一起使用,来连接到主机或建立一个服务器

注意: QHostAddress不做DNS查询,而QHostInfo是有必要的。

这个类还支持通用预定义地址NullLocalHostLocalHostIPv6BroadcastAny


    //setAddress()设置主机地址
    void setAddress(quint32 ip4Addr);
    void setAddress(quint8 *ip6Addr);   // ### Qt 6: remove me
    void setAddress(const quint8 *ip6Addr);
    void setAddress(const Q_IPV6ADDR &ip6Addr);
    void setAddress(const sockaddr *address);
    bool setAddress(const QString &address);

    //protocol()检查协议类型
    QAbstractSocket::NetworkLayerProtocol protocol() const;
    //toIPv4Address()、toIPv6Address()或toString()来检索主机地址
    quint32 toIPv4Address() const; // ### Qt6: merge with next overload
    quint32 toIPv4Address(bool *ok) const;
    Q_IPV6ADDR toIPv6Address() const;
    QString toString() const;


2 > QHostAddress:: SpecialAddress


QHostAddress::SpecialAddress
常量描述
QHostAddress::Null0空地址对象,相当于QHostAddress()
QHostAddress::LocalHost2IPv4本地主机地址,相当于QHostAddress(“127.0.0.1”)
QHostAddress::LocalHostIPv63IPv6本地主机地址,相当于 QHostAddress(“::1”)
QHostAddress::Broadcast1Pv4广播地址,相当于QHostAddress(“255.255.255.255”)
QHostAddress::AnyIPv46相当于QHostAddress(“0.0.0.0”)。与该地址绑定的socket将只监听IPv4接口
QHostAddress::AnyIPv65相当于QHostAddress(“::”)。与该地址绑定的socket将只监听IPv6接口
QHostAddress::Any4双any-address栈,与该地址绑定的socket将侦听IPv4和IPv6接口


3 > 常用函数


    //返回主机地址的网络层协议
    QAbstractSocket::NetworkLayerProtocol protocol() const;
    //返回IPv4地址为一个数字
    //例如地址是127.0.0.1,返回值为2130706433(即0x7f000001)
    quint32 toIPv4Address() const; // ### Qt6: merge with next overload
    quint32 toIPv4Address(bool *ok) const;
    //返回的IPv6地址为Q_IPV6ADDR结构。该结构由16位无符号字符组成
    Q_IPV6ADDR toIPv6Address() const;

    //返回地址为一个字符串
    //例如地址是IPv4地址127.0.0.1,返回的字符串为“127.0.0.1”
    QString toString() const;
    
    //返回IPv6地址的范围ID。对于IPv4地址,如果该地址不包含范围ID,则返回一个空字符串
    QString scopeId() const;
    //若主机地址为空(INADDR_ANY 或 in6addr_any),返回true
    bool isNull() const;

    //若地址是IPv6的环回地址,或任何IPv4的环回地址,则返回true
    bool isLoopback() const; 


4 > IPv6 的范围 ID


IPv6 的范围 ID 指定非全球 IPv6 地址范围的可达性,限制地址可以被使用的区域。

所有 IPv6 地址与这种可达范围相关联。范围 ID 用于消除那些不能保证是全局唯一性的地址。

IPv6 指定以下四个层次的可达性:

A .  节点本地(Node-local):地址仅用于和在相同的接口(例如:环回接口是“::1”)上的服务进行通信。

B .  链路-本地(Link-local):地址是本地网络接口(链接),每个IPv6接口上总有一个链路-本地地址在你的主机上。链路-本地地址(“fe80…”)由本地网络适配器的MAC地址生成,不保证是唯一的。

C .  本地-站点(Site-local):地址是本地的网站/私有网络(例如,公司内网)地址。本地-站点地址(“fec0…”)通常是由网站路由器分布,本地站点之外不能保证是唯一的。

D .  全球(Global):用于全球可路由地址,例如:Internet上的公共服务器。

当使用链路-本地或本地-站点地址的IPv6连接,必须指定范围ID。对链路-本地地址来说,范围ID通常与接口名称(例如,“eth0”、“en1”)或数目(例如,“1”、“2”)相同​



4、 QNetworkInterface 详解


1 > QNetworkInterface 类:负责提供主机IP地址和网络接口的列表,表示了当前程序正在运行时与主机绑定的一个网络接口。

每个网络接口可能包含0或者多个IP地址,每个IP地址都可选择性地与一个子网掩码和(或)一个广播地址相关联。

只有 IPv4 地址可以保证在所有平台上都能列举所有这些特性,而 IPv6 地址,目前只支持Windows XP及相关版本、LinuxMacOS 和 BSDs 可列举所有。


2 > 常用函数


    /*********************************************
     * 返回网络接口的名称;
     * 在Unix系统中,这是一个包含接口的类型和任选的序列号的字符串,例如:“eth0”、“lo”或者“pcn0”;
     * 在Windows中,这是一个内部ID,用户不能更改
    **********************************************/
    QString name() const;
    /*********************************************
     * 如果名称可确定,在Windows上,返回网络接口的人类可读的名称,例如:“本地连接”;
     * 如果不能,这个函数返回值与name()相同。
     * 用户可以在Windows控制面板中修改人类可读的名称,因此它可以在程序的执行过程中变化的名称。
     * 在Unix上,此函数目前返回值总是和name()相同,因为Unix系统不存储人类可读的名称的配置。
    **********************************************/
    QString humanReadableName() const;
    //返回与此网络接口关联的标志
    InterfaceFlags flags() const;
    //返回网络接口的底层硬件地址。如以太网接口,表示MAC地址的字符串,用冒号分隔。其他接口类型可能使用其他类型的硬件地址
    QString hardwareAddress() const;
    //返回IP地址列表及其相关的网络掩码和广播地址
    QList<QNetworkAddressEntry> addressEntries() const;


    //返回的主机上找到的所有的网络接口的列表;在失败情况下,它会返回一个空列表
    static QList<QNetworkInterface> allInterfaces();
    //仅返回IP地址列表
    static QList<QHostAddress> allAddresses();


3 > 网络接口相关的标识


QNetworkInterface::InterfaceFlags
常量描述
QNetworkInterface::IsUp0x1网络接口处于活动状态
QNetworkInterface::IsRunning0x2网络接口已分配资源
QNetworkInterface::CanBroadcast0x4网络接口工作在广播模式
QNetworkInterface::IsLoopBack0x8网络接口是环回接口:也就是说,它是一个虚拟接口,其目的是主机本身
QNetworkInterface::IsPointToPoint0x10网络接口是一个点对点接口:也就是说,有一个,单一的其他地址可以直接由它到达
QNetworkInterface::CanMulticast0x20网络接口支持多播

注意:一个网络接口不能既是broadcast-based又是point-to-point


5、 QNetworkAddressEntry 详解


1 > QNetworkAddressEntry 类:存储了一个网络接口所支持的一个IP地址,同时还有与之相关的子网掩码广播地址

每个网络接口可以包含0个多个IP地址,这些IP地址可以分别关联一个子网掩码和(或)一个广播地址(取决于操作系统的支持)


2 > 常用函数


    //返回一个网络接口中存在的IPv4或IPv6地址;
    QHostAddress ip() const;

    /**************************************
     *返回与IP地址相关联的子网掩码。
     * 子网掩码是一个IP地址的形式表示,如255.255.0.0。
     * 对于IPv6地址,前缀长度被转换成一个地址,其中设置为1的位数等于前缀长度。
     * 前缀长度为64位(最常见的值),子网掩码将被表示为一个地址为FFFF:FFFF:FFFF:FFFF::的QHostAddress
    ****************************************/
    QHostAddress netmask() const;

    /**************************************
     *返回此IP地址的前缀长度。前缀长度和子网掩码中设置为1的位数相匹配。
     * IPv4地址的值在0 - 32之间。IPv6地址的值在0 - 128之间,是表示数据的首选。
     * 如果前缀长度不能确定,则返回0(即:netmask()返回一个空的QHostAddress());
     * 例如:255.255.240.0 转换为二进制:11111111 11111111 11110000 00000000,
     * 那么前缀长度就是8*2 + 4 = 20(1的个数)
    ****************************************/
    int prefixLength() const;

    //返回IPv4地址和子网掩码相关联的广播地址;
    //对于IPv6地址来说,返回的总是空,因为广播的概念已被抛弃,为了系统支持多播;
    QHostAddress broadcast() const;




3 > 例子


    QList<QNetworkInterface> list = QNetworkInterface::allInterfaces();
    foreach (QNetworkInterface netInterface, list) {
        QList<QNetworkAddressEntry> entryList = netInterface.addressEntries();
        foreach(QNetworkAddressEntry entry, entryList) {  // 遍历每一个IP地址
            qDebug() << "********************";
            qDebug() << "IP Address:" << entry.ip().toString();  // IP地址
            qDebug() << "Netmask:" << entry.netmask().toString();  // 子网掩码
            qDebug() << "Broadcast:" << entry.broadcast().toString();  // 广播地址
            qDebug() << "Prefix Length:" << entry.prefixLength();  // 前缀长度
        }
    }







  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值