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

浙公网安备 33010602011771号