文章目录
- 一、Qt 网络模块介绍
- 二、主机信息查询
- 1.QHostlnfo 和 QNetworkInterface 类
- 2.QHostlnfo 的使用
- 2.1 获取本机主机名和 IP 地址
- 2.2 查找主机的地址信息
- 3.QNetworkInterface 的使用
Qt 网络模块:
-
Qt基础 | 主机信息查询 | QHostInfo的介绍和使用 | QNetworkInterface的介绍和使用
-
Qt基础 | TCP通信 | TCP服务端与客户端程序设计 | QTcpServer | QTcpSocket
-
Qt基础 | UDP通信 | UDP单播、广播、组播的介绍与实现
-
Qt基础 | 基于HTTP协议的网络文件下载
一、Qt 网络模块介绍
Qt 网络模块提供用于编写 TCP/IP 客户端和服务器端程序的各种类,如用于 TCP 通信的 QTcpSocket 和 QTcpServer,用于 UDP 通信的 QUdpSocket,还有用于实现 HTTP、FTP等普通网络协议的高级类如:QNetworkRequest、QNetworkReply 和 QNetworkAccessManager。Qt 网络模块还提供用于网络代理、网络承载管理的类,提供基于安全套接字层(SSL)协议的安全网络通信的类。
要在程序中使用Qt 网络模块,需要在项目配置文件中增加一条配置语句:
Qt += network
下面介绍基本的 TCP 和 UDP 网络通信类的使用,基于 HTTP 的网络下载管理的实现。
二、主机信息查询
1.QHostlnfo 和 QNetworkInterface 类
查询一个主机的 MAC地址或 IP 地址是网络应用程序中经常用到的功能, Qt 提供了 QHostInfo 和 QNetworklnterface 类可以用于此类信息的查询。
QHostlnfo类的常用函数如下:
QNetworklnterface 可以获得运行应用程序的主机的所有 IP 地址和网络接口列表。静态函数alllnterfaces() 返回主机上所有的网络接口的列表,一个网络接口可能包括多个 IP 地址,每个 IP地址与掩码或广播地址关联。如果无需知道子网掩码和广播的 IP 地址,使用静态函数 allAddresses()可以获得主机上的所有 IP 地址列表 。
QNetworklnterface类的常用函数如下:
2.QHostlnfo 的使用
2.1 获取本机主机名和 IP 地址
首先,通过QHostlnfo::localHostName()
函数获取本机主机名 hostName,然后再使用主机名作为参数,通过 QHostlnfo::fromName(QString &name)
函数返回指定主机名的主机信息 hostInfo。hostInfo 是 QHostInfo 的实例,通过其函数 addresses()
获取主机的 IP 地址列表 addList。返回的 addList 是 QHostAddress 类的列表。QHostAddress 类提供了一个 IP 地址信息,包括了 IPv4 地址和 IPv6 地址,有两个主要的函数:
-
protocol()
函数返回
QAbstractSocket::NetworkLayerProtocol
枚举类型变量 ,表示当前 IP 地址的协议类型枚举值如下:
-
toString()
函数返回 IP 地址的字符串
程序如下:
void Dialog::on_btnGetHostInfo_clicked()
{//QHostInfo获取主机信息
// ui->plainTextEdit->clear();
QString hostName=QHostInfo::localHostName();//本地主机名
ui->plainTextEdit->appendPlainText("本机主机名:"+hostName+"\n");
QHostInfo hostInfo=QHostInfo::fromName(hostName); //本机IP地址
QList<QHostAddress> addList=hostInfo.addresses();//IP地址列表
if (!addList.isEmpty())
for (int i=0;i<addList.count();i++)
{
QHostAddress aHost=addList.at(i); //每一项是一个QHostAddress
bool show=ui->chkOnlyIPv4->isChecked();//只显示IPv4
if (show)
show=(QAbstractSocket::IPv4Protocol==aHost.protocol()); //协议类型,
else
show=true;
if (show) {
ui->plainTextEdit->appendPlainText("协 议:"+protocolName(aHost.protocol()));//协议类型
ui->plainTextEdit->appendPlainText("本机IP地址:"+aHost.toString()); //IP地址
ui->plainTextEdit->appendPlainText("");
}
}
}
QString Dialog::protocolName(QAbstractSocket::NetworkLayerProtocol protocol)
{//通过协议类型返回协议名称
switch(protocol)
{
case QAbstractSocket::IPv4Protocol:
return "IPv4 Protocol";
case QAbstractSocket::IPv6Protocol:
return "IPv6 Protocol";
case QAbstractSocket::AnyIPProtocol:
return "Any IP Protocol";
default:
return "Unknown Network Layer Protocol";
}
}
单击 “QHostInfo 获取本机主机名和 IP 地址” 按钮,如果勾选了 “只显示 IPv4 协议地址” 复选框,就只显示本机的 IPv4 地址,否则显示所有的 IP 地址信息。
2.2 查找主机的地址信息
QHostInfo 的静态函数 QHostInfo::lookupHost()
函数可以根据主机名、域名或 IP 地址查找主机的地址信息。lookupHost() 函数原型如下:
[static] int QHostInfo::lookupHost(const QString &name, QObject *receiver, const char *member)
-
函数说明:
用于查找与主机名
name
关联的IP地址,当查询结果准备好时,会在receiver
对象中调用member
槽或信号,并使用QHostInfo
参数。然后可以检查QHostInfo
对象以获取查询结果。如果将字面IP地址传递给
name
而不是主机名,QHostInfo
将为IP地址搜索域名(即,QHostInfo
将执行反向查询)。成功时,结果的QHostInfo
将包含解析后的域名和主机名的IP地址。 -
参数说明:
- 参数 name 是表示主机名的字符串,可以是一个主机名、一个域名或者是一个IP地址
- 参数 receiver 指定了一个响应槽函数的接收者
- 参数 member 指定了一个响应槽函数的槽函数名称
-
示例:
QHostInfo::lookupHost("www.kde.org", this, SLOT(lookedUp(QHostInfo))); void MyWidget::lookedUp(const QHostInfo &host) { if (host.error() != QHostInfo::NoError) { qDebug() << "Lookup failed:" << host.errorString(); return; } const auto addresses = host.addresses(); for (const QHostAddress &address : addresses) qDebug() << "Found address:" << address.toString(); }
执行 lookupHost()
函数后,程序可能需要花一定的时间来查找主机地址,但是不会阻塞程序的运行。当查找到主机地址后,通过信号通知设定的槽函数,在槽函数里读取查找的结果。函数返回一个表示查找的 ID。
程序如下:
void Dialog::on_btnLookup_clicked()
{//查找主机信息
QString hostname=ui->editHost->text(); //主机名
ui->plainTextEdit->appendPlainText("正在查找查找主机信息:"+hostname);
QHostInfo::lookupHost(hostname,this,SLOT(lookedUpHostInfo(QHostInfo)));
}
void Dialog::lookedUpHostInfo(const QHostInfo &host)
{//查找主机信息的槽函数
// ui->plainTextEdit->clear();
QList<QHostAddress> addList=host.addresses();//
if (!addList.isEmpty())
for (int i=0;i<addList.count();i++)
{
QHostAddress aHost=addList.at(i);
bool show=ui->chkOnlyIPv4->isChecked();//只显示IPv4
if (show)
show=QAbstractSocket::IPv4Protocol==aHost.protocol();
else
show=true;
if (show) {
ui->plainTextEdit->appendPlainText("协 议:"+protocolName(aHost.protocol()));
ui->plainTextEdit->appendPlainText(aHost.toString());
}
}
}
单击 “QHostInfo 查找域名的 IP 地址” 按钮,
3.QNetworkInterface 的使用
QNetworklnterface 可以获得运行应用程序的主机的所有网络接口,包括其子网掩码和广播地址等。静态函数 QNetworklnterface::allInterfaces()
函数用于获取所有网络接口的列表,通过 humanReadableName()
函数获取网络接口名称。通过 hardwareAddress()
函数获取 MAC 地址。通过 addressEntries()
函数获取当前网络接口的 IP 地址列表(包括子网掩码与广播地址)。这个 IP 地址列表是 QNetworkAddressEntry
类型的地址列表。QNetworkAddressEntry类提供了一个网络接口的 IP 地址、子网掩码和广播地址,有三个主要的函数:
-
ip() 函数
返回网络接口的 IP 地址
-
netmask() 函数
返回网络接口的子网掩码
-
broadcast() 函数
返回网络接口的广播地址
如果无需直到子网掩码和广播地址等信息,可以使用 QNetworklnterface::allAddress()
只获取 IP 地址。QNetworklnterface::allAddress()
的功能与 QHostInfo::addresses()
函数类似,都是返回一个 QHostAddress 的列表。只是 QNetworklnterface 会返回更多的地址,包括表示本机的 127.0.0.1,而 QHostInfo 不会返回这个 IP 地址。
程序如下:
void Dialog::on_btnALLInterface_clicked()
{//QNetworkInterface::allInterfaces()函数的使用
// ui->plainTextEdit->clear();
QList<QNetworkInterface> list=QNetworkInterface::allInterfaces();
for(int i=0;i<list.count();i++)
{
QNetworkInterface aInterface=list.at(i);
if (!aInterface.isValid())
continue;
ui->plainTextEdit->appendPlainText("设备名称:"+aInterface.humanReadableName());
ui->plainTextEdit->appendPlainText("硬件地址:"+aInterface.hardwareAddress());
QList<QNetworkAddressEntry> entryList=aInterface.addressEntries();
for(int j=0;j<entryList.count();j++)
{
QNetworkAddressEntry aEntry=entryList.at(j);
ui->plainTextEdit->appendPlainText(" IP 地址:"+aEntry.ip().toString());
ui->plainTextEdit->appendPlainText(" 子网掩码:"+aEntry.netmask().toString());
ui->plainTextEdit->appendPlainText(" 广播地址:"+aEntry.broadcast().toString()+"\n");
}
ui->plainTextEdit->appendPlainText("\n");
}
}
单击 “QNetworkInterface::allInterfaces()”
程序如下:
void Dialog::on_btnDetail_clicked()
{//QNetworkInterface::allAddresses()的使用
// ui->plainTextEdit->clear();
QList<QHostAddress> addList=QNetworkInterface::allAddresses();//
if (!addList.isEmpty())
for (int i=0;i<addList.count();i++)
{
QHostAddress aHost=addList.at(i);
bool show=ui->chkOnlyIPv4->isChecked();//只显示IPv4
if (show)
show=QAbstractSocket::IPv4Protocol==aHost.protocol();
else
show=true;
if (show)
{
ui->plainTextEdit->appendPlainText("协 议:"+protocolName(aHost.protocol()));
ui->plainTextEdit->appendPlainText("IP地址:"+aHost.toString());
ui->plainTextEdit->appendPlainText("");
}
}
}
单击 “QNetworklnterface::allAddress()”,