bool QHostAddress::isGlobal() const
Returns true if the address is an IPv4 or IPv6 global address, false otherwise. A global address is an address that is not reserved for special purposes (like loopback or multicast) or future purposes.
自定义函数protocolName(),通过协议类型返回协议名称字符串。
c复制代码
//通过协议类型返回协议名称字符串
QString Widget::protocolName(QAbstractSocket::NetworkLayerProtocol protocol)
{
switch (protocol) {
case QAbstractSocket::IPv4Protocol:
return "IPV4";
case QAbstractSocket::IPv6Protocol:
return "IPV6";
case QAbstractSocket::AnyIPProtocol:
return "Any Internet Protocol";
default:
return "Unknown NetWork Layer Protocol";
}
}
查找主机地址信息
static\] int QHostInfo::**lookupHost(const QString \&name, QObject \*receiver, const char \*member)**: name表示主机名的字符串,可以是主机名、域名或IP地址;receive和member指定接收者和槽函数名称。
```c
//查找域名的IP地址
void Widget::on_btnLookkup_clicked()
{
ui->plainTextEdit->clear();
QString hostName = ui->comboBox->currentText(); //读取主机名
ui->plainTextEdit->appendPlainText("Searching for host information:"+hostName+"\n");
QHostInfo::lookupHost(hostName, this,SLOT(do_lookedUpHostInfo(QHostInfo)));
}
//查找主机信息的槽函数
void Widget::do_lookedUpHostInfo(const QHostInfo &host)
{
QList addrList = host.addresses(); //获取主机地址列表
if(addrList.isEmpty())return;
foreach(QHostAddress host, addrList)
{
bool show = ui->checkBox_OnlyIPV4->isChecked(); //只显示ipv4
//Returns the network layer protocol of the host address.
show = show ? (host.protocol() == QAbstractSocket::IPv4Protocol):true;
if(show){
ui->plainTextEdit->appendPlainText("protool:"+protocolName(host.protocol()));//协议
ui->plainTextEdit->appendPlainText(host.toString());
ui->plainTextEdit->appendPlainText(QString("isGolbal() = %1\n").arg(host.isGlobal()));
}
}
}
```
3. QNetworkInterface类的使用
```c
//根据枚举值返回字符串
QString Widget::interfaceType(QNetworkInterface::InterfaceType type)
{
switch(type){
case QNetworkInterface::Unknown:
return "Unkown";
case QNetworkInterface::Loopback:
return "Loopback";
case QNetworkInterface::Ethernet:
return "Etherent";
case QNetworkInterface::Wifi:
return "Wifi";
default:
return "Other type";
}
}
//allInterfaces()
void Widget::on_btnAllInterface_2_clicked()
{
ui->plainTextEdit->clear();
QList list = QNetworkInterface::allInterfaces();//网络接口列表
foreach(QNetworkInterface interface,list){
if(!interface.isValid())
continue;
// The name of the device
// Hardware devices
// Interface type
// Subnet mask
// broadcast address
ui->plainTextEdit->appendPlainText("The name of the device:"+interface.humanReadableName());
ui->plainTextEdit->appendPlainText("Hardware devices:"+interface.hardwareAddress());
ui->plainTextEdit->appendPlainText("Interface type:"+interfaceType(interface.type()));
QList entryList = interface.addressEntries();//地址列表
foreach(QNetworkAddressEntry entry, entryList){
ui->plainTextEdit->appendPlainText(" IP Address:"+entry.ip().toString());
ui->plainTextEdit->appendPlainText(" Subnet mask:"+entry.netmask().toString());
ui->plainTextEdit->appendPlainText(" broadcast address:"+entry.broadcast().toString()+"\n");
}
}
}
//alladdress
void Widget::on_btnAllAddress_clicked()
{
ui->plainTextEdit->clear();
QList addrelist = QNetworkInterface::allAddresses();//IP地址列表
if(addrelist.isEmpty()) return;
foreach(QHostAddress host, addrelist){
bool show = ui->checkBox_OnlyIPV4->isChecked();
show = show ? (host.protocol() == QAbstractSocket::IPv4Protocol):true;
if(show){
ui->plainTextEdit->appendPlainText("protocol:"+protocolName(host.protocol()));
ui->plainTextEdit->appendPlainText("IP Address:"+host.toString());
ui->plainTextEdit->appendPlainText(QString("isGrobal() = %1\n").arg(host.isGlobal()));
}
}
}
```
Loopback:
回送地址(Loopback Address)是本机回送地址(127.X.X.X),即主机IP堆栈内部的IP地址,主要用于网络软件测试以及本地机进程间通信。因此,无论什么程序,一旦使用回送地址发送数据,协议软件会立即将其返回,不进行任何网络传输。
127.0.0.1是回送地址,又指本地机,一般用来测试使用。
### 项目2:基于HTTP的网络应用程序
QNetworkRequest 类通过 URL 发起网络协议请求,其也保存网络请求的信息,目前支持 HTTP、
FTP 和本地文件 URL 的下载或上传。
QNetworkAccessManager 类用于协调网络操作,在 QNetworkRequest 发起网络请求后,
QNetworkAccessManager 负责发送网络请求,以及创建网络响应。
QNetworkReply 类表示网络请求的响应,由 QNetworkAccessManager 在发送网络请求后创建网
络响应。QNetworkReply 提供的信号 finished()、readyRead()、downloadProgress()可用于监测网络响
应的执行情况,从而进行相应的操作。
发起网络协议请求 发送网络请求,以及创建网络响应 监测网络响应

#### 2.1 项目中用到的函数详解
1. clearButtonEnabled : bool
此属性用于保存行编辑在不为空时是否显示清除按钮。
如果启用,行编辑在包含一些文本时会显示一个尾随清除按钮,否则,行编辑不会显示清除按钮(默认值)。
2. **默认路径按钮功能:**
* \[static\] QString QDir::currentPath()
返回应用进程当前目录的绝对路径。当前目录是使用 QDir::setCurrent() 设置的最后一个目录,或者,如果从未调用过,则为父进程启动此应用进程的目录。
* bool QDir::mkdir(const QString \&dirName) const
创建一个名为 dirName 的子目录。
3. **下载按钮功能:**
* QString QString::trimmed() const
返回一个字符串,该字符串删除了开头和结尾的空格。
* \[static\] QUrl QUrl::fromUserInput(const QString \&userInput)
从用户提供的 userInput 字符串返回有效的 URL(如果可以扣除)。如果不可能,则返回无效的 QUrl()。
* QString QUrl::errorString() const
如果修改此 QUrl 对象的最后一个操作遇到解析错误,则返回错误消息。如果未检测到错误,则此函数返回一个空字符串,isValid() 返回 true。
* QString QUrl::fileName(QUrl::ComponentFormattingOptions options = FullyDecoded) const
返回文档名,不包括目录路径。
* bool QFile::remove()
删除 fileName() 指定的文档。如果成功,则返回 true;否则返回 false。文档在删除之前已关闭。
* QNetworkReply \*QNetworkAccessManager::get(const QNetworkRequest \&request)
发布一个请求以获取目标请求的内容,并返回一个新的 QNetworkReply 对象,该对象打开以供读取,每当新数据到达时,该对象都会发出 readyRead() 信号。将下载内容以及相关的标题。
* \[signal\] void QIODevice::readyRead()
每当有新数据可用时,此信号就会发出一次从设备的当前读取信道读取。只有当有新数据可用时,它才会再次发出,例如,当新的网络数据有效负载到达您的网络套接字时,或者当新的数据块附加到您的设备时。
* \[signal\] void QNetworkReply::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
发出此信号以指示此网络请求的下载部分的进度(如果有)。如果没有与此请求关联的下载,则此信号将发出一次,其中 0 作为 bytesReceived 和 bytesTotal 的值。
* \[signal\] void QNetworkReply::finished()
当回复完成处理时,将发出此信号。发出此信号后,回复的数据或元数据将不再更新。
4. 读取下载数据
* qint64 QIODevice::write(const char \*data, qint64 maxSize)
将数据中最多 maxSize 字节的数据写入设备。返回实际写入的字节数,如果发生错误,则返回 -1。
* QByteArray QIODevice::readAll()
从设备读取所有剩余数据,并将其作为字节数组返回。
#### 2.2 主要源码
头文件
```c
#ifndef WIDGET_H
#define WIDGET_H
#include
#include
#include
#include
#include
#include
#include
#include
#include
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
private:
QNetworkAccessManager networkManager; //网络管理
QNetworkReply *reply; //网络响应
QFile *downloadedFile; //下载保存的临时文件
public:
explicit Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void do_finished();
void do_readyRead();
void do_downloadProgress(qint64 bytesRead, qint64 totalBytes);
void on_btnDownload_clicked();
void on_btnDefaultPath_clicked();
void on_editURL_textChanged(const QString &arg1);
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
```
源文件
```c
#include "widget.h"
#include "ui_widget.h"
#include
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
//clearButtonEnabled : bool
//This property holds whether the line edit displays a clear button when it is not empty.
//If enabled, the line edit displays a trailing clear button when it contains some text,
// otherwise the line edit does not show a clear button (the default).
ui->editURL->setClearButtonEnabled(true);
this->setLayout(ui->verticalLayout);
}
Widget::~Widget()
{
delete ui;
}
void Widget::do_finished()
{//网络响应结束
QFileInfo fileInfo(downloadedFile->fileName()); //获取下载文件的文件名
downloadedFile->close();
delete downloadedFile; //删除临时文件
reply->deleteLater(); //由主事件循环删除此文件对象
if(ui->checkBoxOpen->isChecked()){
QDesktopServices::openUrl(QUrl::fromLocalFile(fileInfo.absoluteFilePath()));
}
ui->btnDownload->setEnabled(true);
}
void Widget::do_readyRead()
{
//读取下载数据
downloadedFile->write(reply->readAll());
// qint64 QIODevice::write(const char *data, qint64 maxSize)
// Writes at most maxSize bytes of data from data to the device.
// Returns the number of bytes that were actually written,
// or -1 if an error occurred.
// QByteArray QIODevice::readAll()
// Reads all remaining data from the device, and returns it as a byte array.
}
void Widget::do_downloadProgress(qint64 bytesRead, qint64 totalBytes)
{//下载进度
ui->progressBar->setMaximum(totalBytes);
//Holds the total amount of data to download in bytes.
ui->progressBar->setValue(bytesRead);
}
//默认了路径 按钮
void Widget::on_btnDefaultPath_clicked()
{
// [static] QString QDir::currentPath()
// Returns the absolute path of the application's current directory.
// The current directory is the last directory set with QDir::setCurrent() or,
// if that was never called,
// the directory at which this application was started at by the parent process.
QString curPath = QDir::currentPath(); //返回当前绝对路径给QString变量
QDir dir(curPath); //定义QDir变量
QString sub = "temp";
// bool QDir::mkdir(const QString &dirName) const
// Creates a sub-directory called dirName.
dir.mkdir(sub); //当前路径下创立名为sub的文件夹
ui->editPath->setText(curPath+"/"+sub+"/"); //设置lineedit的文字
}
//下载按钮,开始下载
void Widget::on_btnDownload_clicked()
{
// QString QString::trimmed() const
// Returns a string that has whitespace removed from the start and the end.
QString urlSpec = ui->editURL->text().trimmed(); //将editURL中的文字给QString变量赋值
//urlspec判空
if(urlSpec.isEmpty()){
QMessageBox::information(this,"error","Please specify the download address");
return;
}
// [static] QUrl QUrl::fromUserInput(const QString &userInput)
// Returns a valid URL from a user supplied userInput string if one can be deducted.
// In the case that is not possible, an invalid QUrl() is returned.
QUrl newUrl = QUrl::fromUserInput(urlSpec); //从urlSpaec里获取url
//newurl判有效
if(!newUrl.isValid()){
// QString QUrl::errorString() const
// Returns an error message if the last operation that modified this QUrl object ran into a parsing error.
// If no error was detected,
// this function returns an empty string and isValid() returns true.
QString info = "The URL is invalid:"+urlSpec+"\n error:"+newUrl.errorString();
QMessageBox::information(this,"error",info);
return;
}
QString tempDir = ui->editPath->text().trimmed(); //临时目录
if(tempDir.isEmpty()){
QMessageBox::information(this,"error","Please specify the download address");
return;
}
QString fullFileName = tempDir + newUrl.fileName(); //文件名
// QString QUrl::fileName(QUrl::ComponentFormattingOptions options = FullyDecoded) const
// Returns the name of the file, excluding the directory path.
if(QFile::exists(fullFileName)){ //如果文件存在
QFile::remove(fullFileName); //删除文件
// bool QFile::remove()
// Removes the file specified by fileName(). Returns true if successful; otherwise returns false.
// The file is closed before it is removed.
}
downloadedFile = new QFile(fullFileName); //创建临时文件
if(!downloadedFile->open(QIODevice::WriteOnly)){
QMessageBox::information(this,"error","Temporary file open error");
}
ui->btnDownload->setEnabled(false);
//发送网络请求,创建网络相应
reply = networkManager.get(QNetworkRequest(newUrl)); //网络响应从网络管理里面获取网络请求
// QNetworkReply *QNetworkAccessManager::get(const QNetworkRequest &request)
// Posts a request to obtain the contents of the target request and
// returns a new QNetworkReply object opened for reading
// which emits the readyRead() signal whenever new data arrives.
// The contents as well as associated headers will be downloaded.
// QObject *QObject::parent() const
// Returns a pointer to the parent object.
connect(reply, SIGNAL(readyRead()), this, SLOT(do_readyRead()));
connect(reply, SIGNAL(downloadProgress(qint64,qint64)),
this, SLOT(do_downloadProgress(qint64,qint64)));
connect(reply, SIGNAL(finished()), this, SLOT(do_finished()));
// [signal] void QIODevice::readyRead()
// This signal is emitted once every time new data is available for
// reading from the device's current read channel.
// It will only be emitted again once new data is available,
// such as when a new payload of network data has arrived on your network socket,
// or when a new block of data has been appended to your device.
// [signal] void QNetworkReply::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
// This signal is emitted to indicate the progress of the download part of
// this network request, if there's any. If there's no download associated with this request,
// this signal will be emitted once with 0 as the value of both bytesReceived and bytesTotal.
// [signal] void QNetworkReply::finished()
// This signal is emitted when the reply has finished processing.
// After this signal is emitted, there will be no more updates to the reply's data or metadata.
}
void Widget::on_editURL_textChanged(const QString &arg1)
{
Q_UNUSED(arg1);
ui->progressBar->setMaximum(100);
ui->progressBar->setValue(0);
}
```
*** ** * ** ***
1. IP地址(Internet Protocol Address)是指互联网协议地址,又译为网际协议地址。IP地址是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。 [↩︎](#↩︎)
2. MAC地址(英语:Media Access Control Address),直译为媒体存取控制位址,也称为局域网地址(LAN Address),MAC位址,以太网地址(Ethernet Address)或物理地址(Physical Address),它是一个用来确认网络设备位置的位址。在OSI模型中,第三层网络层负责IP地址,第二层数据链路层则负责MAC位址。MAC地址用于在网络中唯一标示一个网卡,一台设备若有一或多个网卡,则每个网卡都需要并会有一个唯一的MAC地址。 [↩︎](#↩︎)