Web网络服务模块——Qt网络模块
早期进行网络编程时要针对TCP、UDP层面进行开发,涉及网络数据包的交换和控制,以及端口的设置等,代码多且繁琐。同时网络支持的协议数量非常多,如FTP、HTTP等,要分别针对各种协议进行编辑是一件麻烦的事情。
早期Qt针对多种协议实现了相应的类,包括QtcpSocket、QFtp等,但在Qt5之后,Qt将所有网络协议模块进行了封装,形成单独的网络程序设计接口,这个接口就是QtNetwork模块中的QNetworkAccessManager类和QNetworkReply类。而早期的QFtp等类则不建议再使用,除非遇到要处理底层网络的情况;也不建议使用QtcpSocket等类。
QNetworkAccessManager类支持应用程序发送网络请求和接受网络应答。无论何种网络协议或网络请求,只要创建QNetworkAccessManager对象,并在创建后进行网络发送请求的通用配置和设置,如代理和缓存的配置以及相关的其他信号,就可以实现网络通信。网络通信的实时状态和通信结果可以使用应答信号获取,这个应答信号就是QNetworkReply类。
QNetworkReply类包含发送给QNetworkAccessManager请求的所有应答数据。与QNetworkRequest类似,这些数据包含一个URL和一些头部信息,以及一些与应答状态相关的信息,再加上应答信息自身的内容。QNetworkReply是一个顺序访问的QIODevice,一旦数据从对象中读取出来,那么该对象就不再持有这些数据。
QNetworkReply类中有几个关键函数用于操作网络通信和获取网络数据,downloadProgress()函数在通信数据传输过程中被发送,表示当前网络数据传输数量;uploadProgress()处理数据上传量化信息。信号函数finished()在网络通信结束时被触发,当这个信号被触发时,就不会再对应答数据或者元数据进行更新。应答信息可以通过read()或readAll()来读取数据,在close()函数调用后放弃所有应答信息。
关于QNetworkAccessManager类更多信息可参考QNetworkAccessManager Class | Qt Network 5.11;关于QNetworkReply类更多信息可参考QNetworkReply Class | Qt Network 5.11。
下面代码实现了一个简单的网络传输例子。代码完成打开某个URL,然后下载并读取这个URL网络数据:
QNetworkAccessManager * manager = new QNetworkAccessManager(this);
connect(manager, SIGNAL(finished(QNetworkReply *)), this,
SLOT(replyFinished(QNetworkReply *)));
manager->get(QNetworkRequest(QUrl("http://www.baidu.com")));
void replyFinished(QNetworkReply * pReply){
qDebug() << pReply->readAll();
}
上述代码中,函数通过当前对象(this)实现信号传递。在replyFinished函数中处理从网络中读取的数据,可以显示或进行修改。
如果要了解网络通信的细节内容,则可以采用另一种网络通信方式,它通过QNetworkReply类对象实现信号传递,具体代码如下:
QNetworkAccessManager * pManager = new QNetworkAccessManager();
QNetworkReply * pReply = pManager->get(QNetworkRequest(url));
//创建信号机制
connect(pReply, QNetworkReply::downloadProgress, this, myDownloadProgress);
connect(pReply, QNetworkReply::finished, this, myFinished);
void myFinished(){
pRelpy->readAll();
}
void myDownloadProgress(qint64 bytesReceived, qint64 bytesTotal){
ui->progressBar->setMaximum(bytesTotal); //处理下载进度,显示到对话框进度条中
ui->progressBar->setValue(bytesReceived);
}
上述代码可实现通过QNetworkReply类对象取得网络通信的详细信息,可以进行数据读取、进度更新等操作。