Qt之QHostAddress

简介: 简述QHostAddress类提供一个IP地址。这个类提供一种独立于平台和协议的方式来保存IPv4和IPv6地址。QHostAddress通常与QTcpSocket、QTcpServer、QUdpSocket一起使用,来连接到主机或建立一个服务器。可以通过setAddress()来设置一个主机地址,使用toIPv4Address()、toIPv6Address

简述

QHostAddress类提供一个IP地址。

这个类提供一种独立于平台和协议的方式来保存IPv4和IPv6地址。

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

可以通过setAddress()来设置一个主机地址,使用toIPv4Address()、toIPv6Address()或toString()来检索主机地址。你可以通过protocol()来检查协议类型。

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

这个类还支持通用的预定义地址:Null、LocalHost、LocalHostIPv6、Broadcast和Any。

常用接口

枚举 QHostAddress::SpecialAddress:

常量 描述
QHostAddress::Null 0 空地址对象,相当于QHostAddress()。
QHostAddress::LocalHost 2 IPv4本地主机地址,相当于QHostAddress(“127.0.0.1”)。
QHostAddress::LocalHostIPv6 3 IPv6本地主机地址,相当于 QHostAddress(“::1”)。
QHostAddress::Broadcast 1 Pv4广播地址,相当于QHostAddress(“255.255.255.255”)。
QHostAddress::AnyIPv4 6 IPv4 any-address,相当于QHostAddress(“0.0.0.0”)。与该地址绑定的socket将只监听IPv4接口。
QHostAddress::AnyIPv6 5 IPv6 any-address,相当于QHostAddress(“::”)。与该地址绑定的socket将只监听IPv4接口。
QHostAddress::Any 4 双any-address栈,与该地址绑定的socket将侦听IPv4和IPv6接口。


bool isLoopback() const

如果地址是IPv6的环回地址,或任何IPv4的环回地址,则返回true。

bool isNull() const

如果主机地址为空(INADDR_ANY 或 in6addr_any),返回true。默认的构造函数创建一个空的地址,这个地址对于任何主机或接口是无效的。

QAbstractSocket::NetworkLayerProtocol protocol() const

返回主机地址的网络层协议。

QString scopeId() const

返回IPv6地址的范围ID。对于IPv4地址,如果该地址不包含范围ID,则返回一个空字符串。

IPv6的范围ID指定非全球IPv6地址范围的可达性,限制地址可以被使用的区域。所有IPv6地址与这种可达范围相关联。范围ID用于消除那些不能保证是全局唯一性的地址。

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

  • 节点本地(Node-local):地址仅用于和在相同的接口(例如:环回接口是”::1”)上的服务进行通信。
  • 链路-本地(Link-local):地址是本地网络接口(链接),每个IPv6接口上总有一个链路-本地地址在你的主机上。链路-本地地址(”fe80…”)由本地网络适配器的MAC地址生成,不保证是唯一的。
  • 本地-站点(Site-local):地址是本地的网站/私有网络(例如,公司内网)地址。本地-站点地址(”fec0…”)通常是由网站路由器分布,本地站点之外不能保证是唯一的。
  • 全球(Global):用于全球可路由地址,例如:Internet上的公共服务器。

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

quint32 toIPv4Address() const
quint32 toIPv4Address(bool * ok) const

返回IPv4地址为一个数字。

例如,如果地址是127.0.0.1,返回值为2130706433(即0x7f000001)。

如果protocol()是IPv4Protocol,该值是有效的;如果是IPv6Protocol,并且IPv6地址是一个IPv4映射的地址,(RFC4291)。在这种情况下,ok将被设置为true;否则,它将被设置为false。

Q_IPV6ADDR toIPv6Address() const

返回的IPv6地址为Q_IPV6ADDR结构。该结构由16位无符号字符组成。

Q_IPV6ADDR addr = hostAddr.toIPv6Address();
// 地址包含16位无符号字符

for (int i = 0; i < 16; ++i) {
    // 处理 addr[i]
}

如果protocol()是IPv6Protocol,该值是有效的;如果是IPv4Protocol,返回地址将是IPv4地址映射的IPv6地址,(RFC4291)。

QString toString() const

返回地址为一个字符串。

例如,如果地址是IPv4地址127.0.0.1,返回的字符串为“127.0.0.1”。对于IPv6字符串格式将按照RFC5952建议。对于QHostAddress::Any,IPv4地址将返回(“0.0.0.0”)

使用

简单应用

构造一个QHostAddress,通过toString()来获取对应的IP地址:

QHostAddress address = QHostAddress(QHostAddress::LocalHost);
QString strIPAddress = address.toString();

显然,如上所述,IP地址为:“127.0.0.1”。

获取所有主机地址

QNetworkInterface类中提供了一个便利的静态函数allAddresses(),用于返回一个QHostAddress主机地址列表。

QList<QHostAddress> list = QNetworkInterface::allAddresses();
foreach (QHostAddress address, list) {
    // 主机地址为空
    if (address.isNull())
        continue;

    qDebug() << "********************";
    QAbstractSocket::NetworkLayerProtocol nProtocol = address.protocol();
    QString strScopeId = address.scopeId();
    QString strAddress = address.toString();
    bool bLoopback = address.isLoopback();

    // 如果是IPv4
    if (nProtocol == QAbstractSocket::IPv4Protocol) {
        bool bOk = false;
        quint32 nIPV4 = address.toIPv4Address(&bOk);
        if (bOk)
            qDebug() << "IPV4 : " << nIPV4;
    }
    // 如果是IPv6
    else if (nProtocol == QAbstractSocket::IPv6Protocol) {
        QStringList IPV6List("");
        Q_IPV6ADDR IPV6 = address.toIPv6Address();
        for (int i = 0; i < 16; ++i) {
            quint8 nC = IPV6[i];
            IPV6List << QString::number(nC);
        }
        qDebug() << "IPV6 : " << IPV6List.join(" ");
    }

    qDebug() << "Protocol : " << nProtocol;
    qDebug() << "ScopeId : " << strScopeId;
    qDebug() << "Address : " << strAddress;
    qDebug() << "IsLoopback  : " << bLoopback;
}

输出如下:


IPV6 : ” 254 128 0 0 0 0 0 0 85 12 171 25 251 72 1 201”
Protocol : QAbstractSocket::NetworkLayerProtocol(IPv6Protocol)
ScopeId : “15”
Address : “fe80::550c:ab19:fb48:1c9%15”
IsLoopback : false


IPV4 : 2851996105
Protocol : QAbstractSocket::NetworkLayerProtocol(IPv4Protocol)
ScopeId : “”
Address : “169.254.1.201”
IsLoopback : false


IPV6 : ” 254 128 0 0 0 0 0 0 208 134 133 102 96 101 137 84”
Protocol : QAbstractSocket::NetworkLayerProtocol(IPv6Protocol)
ScopeId : “11”
Address : “fe80::d086:8566:6065:8954%11”
IsLoopback : false


IPV4 : 2886861989
Protocol : QAbstractSocket::NetworkLayerProtocol(IPv4Protocol)
ScopeId : “”
Address : “172.18.4.165”
IsLoopback : false


IPV6 : ” 254 128 0 0 0 0 0 0 248 100 169 98 114 25 249 142”
Protocol : QAbstractSocket::NetworkLayerProtocol(IPv6Protocol)
ScopeId : “16”
Address : “fe80::f864:a962:7219:f98e%16”
IsLoopback : false


IPV4 : 3232239873
Protocol : QAbstractSocket::NetworkLayerProtocol(IPv4Protocol)
ScopeId : “”
Address : “192.168.17.1”
IsLoopback : false


IPV6 : ” 254 128 0 0 0 0 0 0 129 105 105 31 20 142 211 203”
Protocol : QAbstractSocket::NetworkLayerProtocol(IPv6Protocol)
ScopeId : “17”
Address : “fe80::8169:691f:148e:d3cb%17”
IsLoopback : false


IPV4 : 3232281089
Protocol : QAbstractSocket::NetworkLayerProtocol(IPv4Protocol)
ScopeId : “”
Address : “192.168.178.1”
IsLoopback : false


IPV6 : ” 254 128 0 0 0 0 0 0 89 150 39 163 131 181 42 231”
Protocol : QAbstractSocket::NetworkLayerProtocol(IPv6Protocol)
ScopeId : “18”
Address : “fe80::5996:27a3:83b5:2ae7%18”
IsLoopback : false


IPV4 : 3232249857
Protocol : QAbstractSocket::NetworkLayerProtocol(IPv4Protocol)
ScopeId : “”
Address : “192.168.56.1”
IsLoopback : false


IPV6 : ” 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1”
Protocol : QAbstractSocket::NetworkLayerProtocol(IPv6Protocol)
ScopeId : “”
Address : “::1”
IsLoopback : true


IPV4 : 2130706433
Protocol : QAbstractSocket::NetworkLayerProtocol(IPv4Protocol)
ScopeId : “”
Address : “127.0.0.1”
IsLoopback : true

我们可以获取到很多地址,有可能包含:本例链路地址、私有的IPV4地址等,但是在应用过程中大部分需要进行过滤。

过滤

  • 本地链路地址

本地链路地址范围:169.254.1.0 - 169.254.254.255
参考:http://en.wikipedia.org/wiki/Private_network

bool isLinkLocalAddress(QHostAddress addr){
    quint32 nIPv4 = addr.toIPv4Address();
    quint32 nMinRange = QHostAddress("169.254.1.0").toIPv4Address();
    quint32 nMaxRange = QHostAddress("169.254.254.255").toIPv4Address();
    if ((nIPv4 >= nMinRange) && (nIPv4 <= nMaxRange)) {
        return true;
    } else {
        return false;
    }
}
  • 私有IPV4地址

私有IPV4地址范围:

  1. 10.0.0.0 - 10.255.255.255
  2. 172.16.0.0 - 172.31.255.255
  3. 192.168.0.0 - 192.168.255.255

参考:http://en.wikipedia.org/wiki/Private_network

bool isLocalIP(QHostAddress addr){
    quint32 nIPv4 = addr.toIPv4Address();
    quint32 nMinRange1 = QHostAddress("10.0.0.0").toIPv4Address();
    quint32 nMaxRange1 = QHostAddress("10.255.255.255").toIPv4Address();

    quint32 nMinRange2 = QHostAddress("172.16.0.0").toIPv4Address();
    quint32 nMaxRange2 = QHostAddress("172.31.255.255").toIPv4Address();

    quint32 nMinRange3 = QHostAddress("192.168.0.0").toIPv4Address();
    quint32 nMaxRange3 = QHostAddress("192.168.255.255").toIPv4Address();

    if ((nIPv4 >= nMinRange1 && nIPv4 <= nMaxRange1)
            || (nIPv4 >= nMinRange2 && nIPv4 <= nMaxRange2)
            || (nIPv4 >= nMinRange3 && nIPv4 <= nMaxRange3)) {
        return true;
    } else {
        return false;
    }
}

更多参考

目录
相关文章
|
Java C++
Qt之QFuture
简述 QFuture 类代表一个异步计算的结果。 要启动一个计算,使用 Qt之Concurrent框架 中的 APIs 之一。 QFuture 允许线程与一个或多个结果同步,这些结果将在稍后的时间点准备就绪,该结果可以是具有默认构造函数和拷贝构造函数的任何类型。如果一个结果在调用 result()、resultAt() 或 results() 函数时不可用,QFutur
1969 0
|
安全 Java
Qt之QThreadPool和QRunnable
简述 QRunnable 是所有 runnable 对象的基类,而 QThreadPool 类用于管理 QThreads 集合。 QRunnable 类是一个接口,用于表示一个任务或要执行的代码,需要重新实现 run() 函数。 QThreadPool 管理和循环使用单独的 QThread 对象,以帮助程序减少创建线程的成本。每个 Qt 应用程序都有一个全局 QThre
3455 0
|
Unix Linux Windows
Qt之QLocalServer
简述 QLocalServer提供了一个基于本地socket的server。 QLocalServer可以接受来自本地socket的连接。通过调用listen(),让server监听来自特定key的连接。 调用nextPendingConnection()来接受一个挂起(等待)的连接作为一个已连接的QLocalSocket。函数返一个QLocalSocket指针,可以被
1936 0
|
存储
Qt之findChild
简述 在Qt编程过程中,通常会有多个部件嵌套,而大多数部件都有父子依赖关系,但是有些情况下不能直接引用子部件,这时我们可以通过父部件来findChild -“查找孩子”。 简述 查找选项 findChild 描述 示例 分析 效果 源码 可能情况 查找选项 枚举Qt::FindChildOption: Qt::FindChildOp
2253 0
|
存储 Windows
Qt之QSizePolicy
简述 QSizePolicy类是一个描述布局水平和垂直方向调整策略的属性。 大小策略会影响布局引擎处理部件的方式,部件加入布局以后,会返回一个QSizePolicy,描述了其水平和垂直方向的大小策略。可以通过QWidget::sizePolicy属性为特定部件设置大小策略。 简述 详细描述 成员类型 公共函数 示例 控制类型 QSizePolicy 默认效果
2037 0
|
存储 安全
Qt之QTemporaryFile
简述 QTemporaryFile类是操作临时文件的I/O设备。 QTemporaryFile用于安全地创建一个独一无二的临时文件。临时文件通过调用open()来创建,并且名称是唯一的(即:保证不覆盖现有文件),该临时文件将随着QTemporaryFile对象的析构被删除。这是一个重要的技术,避免了存储在临时文件的应用程序数据损坏。文件名可以自动生成,也可以基于模板(传参
1245 0
|
Web App开发 调度 Windows
Qt之QDesktopServices
简述 QDesktopServices类提供的函数用于访问常见的桌面服务。 许多桌面环境都会提供一系列服务,可以通过应用程序来执行常见任务,如:以用户应用程序首选项的方式,打开一个网页。 此类包含为服务提供简单接口的函数,返回值表明执行成功或失败。 openUrl()函数用于打开位于任意外部应用程序的URL文件。如果URL对应于本地文件系统的资源(URL scheme
2526 0