Qt之QHostAddress

简述

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

时间: 2024-08-30 04:54:34

Qt之QHostAddress的相关文章

Qt之QNetworkAddressEntry

简述 QNetworkAddressEntry类由网络接口支持,存储了一个IP地址,子网掩码和广播地址. 每个网络接口可以包含零个或多个IP地址,进而可以关联到一个子网掩码和/或一个广播地址(取决于操作系统的支持). 这个类代表一个这样的组. 简述 常用接口 使用 更多参考 常用接口 QHostAddress broadcast() const 返回IPv4地址和子网掩码相关联的广播地址. 对于IPv6地址来说,返回的总是空,因为广播的概念已被抛弃,为了系统支持多播. QHostAddress

将vim作为QT开发的IDE

转载请注明链接与作者huihui1988 用了一段时间的vim,喜欢上了这种简洁高效的编辑器.恰逢正在学习QT中,于是将vim变成了开发QT的工具.以下是具体配置. 一.语法高亮支持: 1.打开VIMDIR/vim72/syntax/cpp.vim,加入 syn keyword cppStatement SLOT,SIGNAL syn keyword cppAccess slots,signals 2.增加QT的类型名: syn keyword cType ActiveQt Q3Accel Q3

Qt之获取本机网络信息(超详细)

经常使用命令行来查看一些计算机的配置信息. 1.首先按住键盘上的“开始键+R键”,然后在弹出的对话框中输入“CMD”,回车 另外,还可以依次点击 开始>所有程序>附件>命令提示符 2.接下来在弹出的命令提示符窗口中输入“ipconfig /all”并按键盘上的回车,(注:ipconfig 命令为查看IP配置信息,参数“all”表示查看所有网卡的全部配置信息) 如下图所示: 那么,在Qt中如何获取主机名.IP.端口.MAC等信息? 主要使用到的类有: QHostInfo QHostAddr

Qt之获取本机网络信息(MAC, IP等等,很全)

经常使用命令行来查看一些计算机的配置信息. 1.首先按住键盘上的“开始键+R键”,然后在弹出的对话框中输入“CMD”,回车 另外,还可以依次点击 开始>所有程序>附件>命令提示符 2.接下来在弹出的命令提示符窗口中输入“ipconfig /all”并按键盘上的回车,(注:ipconfig 命令为查看IP配置信息,参数“all”表示查看所有网卡的全部配置信息) 如下图所示: 那么,在Qt中如何获取主机名.IP.端口.MAC等信息? 主要使用到的类有: QHostInfo QHostAddr

简单Qt网络通信

最近要用到Qt的Socket部分,网上关于这部分的资料都比较复杂,我在这总结一下,把Socket的主要部分提取出来,实现TCP和UDP的简单通信. 1.UDP通信 UDP没有特定的server端和client端,简单来说就是向特定的ip发送报文,因此我把它分为发送端和接收端. 注意:在.pro文件中要添加QT += network,否则无法使用Qt的网络功能. 1.1.UDP发送端 1 #include <QtNetwork> 2 QUdpSocket *sender; 3 sender =

Qt浅谈之十六:TCP和UDP(之一)

一.简介 Qt使用QtNetwork模块来进行网络编程,提供了一层统一的套接字抽象用于编写不同层次的网络程序,避免了应用套接字进行网络编的繁琐(因有时需引用底层操作系统的相关数据结构).有较底层次的类如QTcpSocket.QTcpServer和QUdpSocket等来表示低层的网络概念:还有高层次的类如QNetworkRequest.QNetworkReply和QNetworkAccessManager使用相同的协议来执行网络操作:也提供了QNetworkConfiguration.QNetw

QT 网络编程二(UDP版本)

QT的UdpSocket接收消息使用原则 第一步:new一个UdpSocket 第二步:调用UdpSocket的bind方法,同时指定端口号 第三步:使用connect将接收消息函数和UdpSocket对象做关联 第四步:在接受消息槽函数当中调用readDatagram接收消息 接收消息 #ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QUdpSocket> class Widget : public Q

【C/C++学院】(20)QT:udp通信

基于QT的UDP协议的通信 #------------------------------------------------- # # Project created by QtCreator 2014-05-22T21:39:26 # #------------------------------------------------- QT += core gui QT += network greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TA

Qt搭建多线程Server

起因是MySQL在Android上没有驱动.也就是说,移动端想要访问远程数据库,必须通过一台(或多台)PC进行中转. 中转PC作为Server,接受来自移动端Socket访问数据库的要求,Server访问数据库,取得数据,通过Socket发送给移动端. Qt写个C/S其实很简单,网上各种教程,硬伤:Server!是!单!线!程! 假设有10000个移动端访问中转Server,那么如果Server是单线程,那么这10000个移动端是排队通信,排队访问数据库,肯定完蛋! 所以Server必须使用多线