10.3 QHostAddress类的使用
10.3 QHostAddress类的使用
#include <QCoreApplication> #include <QHostAddress> #include <QDebug> #include <QFile> #include <unistd.h> #include <QDataStream> #include <QPair> #include <sys/types.h> #include <arpa/inet.h> int main(int argc, char *argv[]) { QCoreApplication theApp(argc, argv); //1.构造器 { /* QHostAddress(QHostAddress::SpecialAddress address)//通过一些特殊的地址来构造QHostAddress QHostAddress(const QHostAddress &address)//拷贝构造 QHostAddress(const QString &address)//通过字符串的IP地址来构造一个QHostAddress对象(IPV4或IPV6都支持) QHostAddress(const sockaddr *sockaddr)//通过我们所熟知的sockaddr结构体构造(这个结构体是原始的socket套接字中很重要的一个结构体,另外还有一个sockaddr_in) QHostAddress(const Q_IPV6ADDR &ip6Addr)//通过Q_IPV6ADDR结构来构造QHostAddress对象 QHostAddress(const quint8 *ip6Addr)//通过使用整数所表示的IPV6地址来构造一个QHostAddress对象 QHostAddress(quint8 *ip6Addr)//同上,只不过参数变成了普通的指针 QHostAddress(quint32 ip4Addr)//通过32位的整数来构造一个IPV4的地址从而构造一个QHostAddress对象 QHostAddress()//空构造器 */ //1.1 QHostAddress(QHostAddress::SpecialAddress address) QHostAddress address0(QHostAddress::SpecialAddress::Any);//相当于是构建一个可以支持IPV4和IPV6的所有的IP地址的HostInfo对象 QHostAddress address1(QHostAddress::SpecialAddress::LocalHost);//通过本地的回环地址构造 QHostAddress address2(QHostAddress::SpecialAddress::LocalHostIPv6);//通过本地的IPV6地址(相当于也是回环地址,只不过是IPV6的) QHostAddress address3(QHostAddress::SpecialAddress::AnyIPv4);//任何的IPV4地址 QHostAddress address4(QHostAddress::SpecialAddress::AnyIPv6);//任何的IPV6地址 QHostAddress address5(QHostAddress::SpecialAddress::Broadcast);//IPV4广播地址(255.255.255.255) qDebug() << address1.toString();//127.0.0.1 qDebug() << address2.toString();//::1 qDebug() << address3.toString();//0.0.0.0 qDebug() << address4.toString();// :: qDebug() << address5.toString();// 255.255.255.255 /* * QHostAddress::Any //这个ANY表示所构建的QHostAddress可以支持任何类型的IP地址(包括IPV4和IPV6),这个一般用在后面要讲的套接字通信里面监听IP地址的时候(表示我想监听来自任意的IP地址) * QHostAddress::AnyIPv6 //这个则表示接受任意的IPV6地址(::) * QHostAddress::AnyIPv4 //接受任意的IPV4地址(0.0.0.0) * QHostAddress::Broadcast //这个表示通过IPV4的广播地址来构造QHostAddress对象,相当于255.255.255.255 * QHostAddress::LocalHostIPv6 //这个表示从本地的IPV6地址来构造QHostAddress对象(::1) * QHostAddress::LocalHost //这个则是使用本地的回环IPV4地址(127.0.0.1) * QHostAddress::Null //空,相当于QHostAddress的空构造器 */ //1.2 QHostAddress(const QHostAddress &address) QHostAddress address6(address1); qDebug() << address6.toString(); //1.3 QHostAddress(const QString &address) QHostAddress address7("192.168.1.1");//通过IPV4地址字符串构造 QHostAddress address8("fd00:6868:6868:0:410:89d3:a82a:c88b");//通过IPV6地址字符串构造 qDebug() << address7.toString(); qDebug() << address8.toString(); //1.4 QHostAddress(const sockaddr *sockaddr) ///1.4.1 这里先准备好sockaddr_in类型的IPV4的地址 sockaddr_in ipv4Addr = {0}; ipv4Addr.sin_family = AF_INET;//IPV4的协议 ipv4Addr.sin_port = htons(8888); inet_aton("192.168.2.14",&ipv4Addr.sin_addr); ///1.4.2 这里还有IPV6的sockaddr_in地址 sockaddr_in ipv6Addr = {0}; ipv6Addr.sin_family = AF_INET6;//IPV6 ipv6Addr.sin_port = htons(9999); inet_aton("fd00:6868:6868:0:410:89d3:a82a:c88b",&ipv6Addr.sin_addr); /// 通过sockaddr来构造QHostAddress对象 QHostAddress address9((sockaddr*)&ipv4Addr);//平时使用的是sockaddr_in,但是这可以通过类型转换,也没有什么影响 QHostAddress address10((sockaddr*)&ipv6Addr); qDebug() << address9.toString(); qDebug() << address10.toString(); //1.5 QHostAddress(const Q_IPV6ADDR &ip6Addr) Q_IPV6ADDR addr;//这个类型实际上就是QIPV6Address addr[0] = 0x10; addr[1] = 0x11; addr[2] = 0x12; addr[3] = 0x13; addr[6] = 0x14; addr[6] = 0x15; addr[7] = 0x16; addr[8] = 0x17; addr[9] = 0x18; addr[10] = 0x19; addr[11] = 0x20; addr[12] = 0x21; addr[13] = 0x22; addr[14] = 0x23; addr[15] = 0x24; QHostAddress address11(addr); qDebug() << address11.toString(); //1.6 QHostAddress(quint8 *ip6Addr) quint8 ip6Addr = 0x123456; QHostAddress address12(&ip6Addr); qDebug() << address12.toString(); //1.7 QHostAddress(const quint8 *ip6Addr) const quint8 ip6 = 0x12231; const quint8*pIp6 = &ip6; QHostAddress address13(pIp6); qDebug() << address13.toString(); //1.8 QHostAddress(quint32 ip4Addr) quint32 ipv4 = 122345531; QHostAddress address14(ipv4); qDebug() << address14.toString(); } //2.QHostAddress重载的一些运算符 { /* QHostAddress &operator=(const QString &address)//operator=,通过字符串来对当前对象赋值 QHostAddress &operator=(const QHostAddress &address)//通过QHostAddress来为当前赋值 bool operator!=(const QHostAddress &other) const bool operator!=(QHostAddress::SpecialAddress other) const QHostAddress &operator=(QHostAddress::SpecialAddress address) bool operator==(const QHostAddress &other) const bool operator==(QHostAddress::SpecialAddress other) const */ //2.1 QHostAddress &operator=(const QString &address) QHostAddress address13; address13.operator=(QString("1.1.1.1")); qDebug() << address13.toString(); //2.2 QHostAddress &operator=(const QHostAddress &address) QHostAddress address14; address14 = address13; qDebug() << address14.toString(); //2.3 bool operator!=(const QHostAddress &other) const qDebug() << address13.operator!=(address14);//false //2.4 bool operator!=(QHostAddress::SpecialAddress other) const qDebug() << address13.operator!=(QHostAddress(QHostAddress::SpecialAddress::AnyIPv4));//true //2.5 QHostAddress &operator=(QHostAddress::SpecialAddress address) address13.operator=(QHostAddress(QHostAddress::SpecialAddress::LocalHost)); qDebug() << address13.toString(); //2.6 bool operator==(const QHostAddress &other) const qDebug() << address13.operator==(address14);//false //2.7 bool operator==(QHostAddress::SpecialAddress other) const qDebug() << address13.operator==(QHostAddress::SpecialAddress::LocalHost);//true } //3.其他的一些成员函数 { //3.1 void QHostAddress::clear() //设置主机的IP地址为空,并且将地址里面的协议设置为QAbstractSocket::UnknownNetworkLayerProtocol QHostAddress address14("192.168.1.1"); address14.clear(); qDebug() << address14; switch(address14.protocol()) { case QAbstractSocket::UnknownNetworkLayerProtocol: qDebug() << "QAbstractSocket::UnknownNetworkLayerProtocol"; break; } //3.2 bool QHostAddress::isBroadcast() const //该函数用于判断是不是IPV4的广播地址(255.255.255.255) QHostAddress address15(QHostAddress::SpecialAddress::Broadcast); QHostAddress address16("192.168.1.1"); qDebug() << "isBroadcast:" << address15.isBroadcast(); qDebug() << "isBroadcast:" << address16.isBroadcast(); //3.3 bool QHostAddress::isEqual(const QHostAddress &other, QHostAddress::ConversionMode mode = TolerantConversion) const //该函数用于判断当前的host的地址是否和other等价 ///这个的第二个参数是转换模式,这个转换模式相当于就是说,比如对于本地路径127.0.0.1就和::1等价 QHostAddress address17(QHostAddress::SpecialAddress::LocalHost); QHostAddress address18(QHostAddress::SpecialAddress::LocalHostIPv6); qDebug() << address17.isEqual(address18,QHostAddress::ConvertLocalHost);//true ///对于第二参数的几个解释 ///QHostAddress::StrictConversion //在比较的时候不要将IPV6地址转换为与之等价的IPV4地址,那么这样一来大多数情况下比较的结果都是不同的 ///QHostAddress::ConvertV4MappedToIPv4 //在比较的时候讲IPV4地址映射为IPV6地址,比如对于一个IPV6地址("::ffff:192.168.1.1")会和IPV4地址("192.168.1.1") ///QHostAddress::ConvertV4CompatToIPv4 //在比较时,将this的IPV4地址转换为适配的IPV6地址,比如对于IPV6("::192.168.1.1")和IPV4("192.168.1.1")相同 ///QHostAddress::ConvertLocalHost //在转换时,将本地的IPV6回环地址和IPV4回环地址进行比较,例如("::1")和("127.0.0.1")等价 ///QHostAddress::ConvertUnspecifiedAddress //所有未被指定的IP地址都被视为相同,别人AnyIPV4和AnyIPv6或者是Any ///QHostAddress::TolerantConversion //等价于设置ConvertUnspecifiedAddress|ConvertLocalHost|ConvertV4CompatToIPv4 qDebug() << address17.isEqual(address18,QHostAddress::StrictConversion);//false QHostAddress address19("::ffff:192.168.1.1"),address20("192.168.1.1"); qDebug() << address19.isEqual(address20,QHostAddress::ConvertV4MappedToIPv4);//true QHostAddress address21("::192.168.1.1"),address22("192.168.1.1"); qDebug() << address21.isEqual(address22,QHostAddress::ConvertV4CompatToIPv4);//true QHostAddress address23(QHostAddress::SpecialAddress::AnyIPv4),address24(QHostAddress::SpecialAddress::AnyIPv6); qDebug() << address23.isEqual(address24,QHostAddress::ConvertUnspecifiedAddress);//true //3.4 bool QHostAddress::isGlobal() const //如果地址是IPV4或IPV6的全局地址,就返回true。全局地址是只不为特殊目的或未来的目的的保留的地址(比如回环地址) QHostAddress address25("127.0.0.1"),address26("::1"),address27("192.168.1.1"); qDebug() << address25.isGlobal();//false qDebug() << address26.isGlobal();//false qDebug() << address27.isGlobal();//true //3.5 bool QHostAddress::isInSubnet(const QHostAddress &subnet, int netmask) const//该成员方法用于判断当前的IP地址是不是在由参数一的网络前缀和网络掩码所描述的子网中 QHostAddress address28("192.168.31.1"); qDebug() << address28.isInSubnet(QHostAddress("192.168.1.1"),765); //3.6 bool QHostAddress::isInSubnet(const QPair<QHostAddress, int> &subnet) const//同上,只不过参数变成了QPair的形式来描述起始地址和子网掩码 QPair<QHostAddress,int>subnets; subnets.first = QHostAddress("192.168.1.0"); subnets.second = 24; QHostAddress address29("192.168.1.1"); qDebug() << address29.isInSubnet(subnets); //3.7 bool QHostAddress::isLinkLocal() const //如果地址是IPV4或IPV6链路的本地地址,就返回true,比如对于IPV4来说,就是169.254.0.0.0这种地址,对于IPV6则是fe10:-:-这种地址 QHostAddress address30("169.254.0.0"); qDebug() << address30.isLinkLocal();//true //3.8 bool QHostAddress::isLoopback() const //判断地址是不是回环地址 QHostAddress address31("127.0.0.1"),address32("::1"); qDebug() << address31.isLoopback();//true qDebug() << address32.isLoopback();//true //3.9 bool QHostAddress::isMulticast() const //如果是多播地址,则返回true(多播是一种点到多点的通信方式),多播地址的范围是224.0.0.0 ~ 239.255.255.255 QHostAddress address33("224.0.0.1"); qDebug() << address33.isMulticast(); //3.10 bool QHostAddress::isNull() const //如果IP地址无效或为空对象,则返回true QHostAddress address34; QHostAddress address35("10000.11111.11111.11111"); qDebug() << address34.isNull(); qDebug() << address35.isNull(); //3.11 bool QHostAddress::isSiteLocal() const //判断IPV6地址是不是站点本地地址 QHostAddress address36("fec0::"); qDebug() << address36.isSiteLocal();//true //3.12 bool QHostAddress::isUniqueLocalUnicast() const //如果是IPV6的唯一本地单播地址,则是true QHostAddress address37("fc00::"); qDebug() << address37.isUniqueLocalUnicast();//true //3.13 [static] QPair<QHostAddress, int> QHostAddress::parseSubnet(const QString &subnet) //该函数用于分析子网中包含的IP和子网信息,并返回网络前缀和前缀的长度 ///这个的用法是: /// IPv4地址/number number的范围是0到32 /// IPv4地址/子网掩码 192.168.1.1/255.255.255.0 /// IPv6地址/number number的范围是0到128 qDebug() << QHostAddress::parseSubnet("192.168.31.6/255.255.255.0"); qDebug() << QHostAddress::parseSubnet("192.168.1.1/23"); qDebug() << QHostAddress::parseSubnet("fd00:6868:6868:0:410:89d3:a82a:c88b/32"); //3.14 QAbstractSocket::NetworkLayerProtocol QHostAddress::protocol() const //返回该IP地址所用的协议层是什么(IPv4还是Ipv6还是任何的协议又或者是未知的协议) QHostAddress address38("192.168.1.1"),address39("fd00:6868:6868:0:410:89d3:a82a:c88b"),address40(QHostAddress::Any); switch(address40.protocol()) { case QAbstractSocket::AnyIPProtocol: qDebug() << "AnyIPProtocol"; break; case QAbstractSocket::IPv4Protocol: qDebug() << "IPV4"; break; case QAbstractSocket::IPv6Protocol: qDebug() << "IPV6"; break; case QAbstractSocket::UnknownNetworkLayerProtocol: qDebug() << "Unknown"; break; } //3.15 QString QHostAddress::scopeId() const//该函数用于获取Ipv6地址的作用域ID,对于IPv4地址,如果没有作用域ID,则返回空串 QHostAddress address41("fd00:6868:6868:0:410:89d3:a82a:c88b"); qDebug() << address41.scopeId(); //3.16 set系列函数 //void QHostAddress::setAddress(quint32 ip4Addr) //void QHostAddress::setAddress(quint8 *ip6Addr) //void QHostAddress::setAddress(const quint8 *ip6Addr) //void QHostAddress::setAddress(const Q_IPV6ADDR &ip6Addr) //void QHostAddress::setAddress(const sockaddr *sockaddr) //bool QHostAddress::setAddress(const QString &address) //void QHostAddress::setAddress(QHostAddress::SpecialAddress address) //这些set系列函数不再赘述 //3.17 void QHostAddress::swap(QHostAddress &other)//交换两个QHostAddress对象 QHostAddress address42("192.168.1.1"),address43("192.168.1.32"); address42.swap(address43); qDebug() << address42; qDebug() << address43; //3.18 quint32 QHostAddress::toIPv4Address() const //常用的方法,将IPv4地址转为整数 // quint32 QHostAddress::toIPv4Address(bool *ok) const QHostAddress address44("192.168.31.6"); bool isOk(false); qDebug() << address44.toIPv4Address(); qDebug() << address44.toIPv4Address(&isOk) << ":" << isOk; //3.19 Q_IPV6ADDR QHostAddress::toIPv6Address() const QHostAddress address45("fd00:6868:6868:0:410:89d3:a82a:c88b"); const Q_IPV6ADDR&addr = address45.toIPv6Address(); for(int i = 0;i < 16;i++) { qDebug() << addr.operator[](i); } //3.20 QString QHostAddress::toString() const //将IPV6货IPV4地址转换为字符串的形式 //3.21 QDataStream &operator<<(QDataStream &out, const QHostAddress &address)//将QHostAddress对象输出到数据流中 //3.22 QDataStream &operator>>(QDataStream &in, QHostAddress &address)//从流读QHostAddress到内存中 QFile file("./hostAddress"); if(file.open(QIODevice::ReadWrite)) { QDataStream stream(&file); stream << QHostAddress("127.0.0.1") << QHostAddress("fd00:6868:6868:0:410:89d3:a82a:c88b"); file.close(); file.open(QIODevice::ReadOnly); stream.setDevice(&file); QHostAddress buf; do { operator>>(stream,buf); qDebug() << buf.toString(); }while(!stream.atEnd()); } else { qDebug() << file.errorString(); } file.close(); } return theApp.exec(); }
本节代码:https://files.cnblogs.com/files/blogs/792763/QHostAddressDemo.zip?t=1720469601&download=true