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

posted @ 2024-07-09 04:13  蜡笔小新Pointer  阅读(102)  评论(0)    收藏  举报