QT:HTTP协议简单应用

2019-07-13 05:19发布

HTTP协议

QNetworkAccessManager
QNetworkReply
《案例》QT实现HTTP文本浏览器

/* HTTP文本浏览器 - 代码演示 */// HttpDialog.h #ifndef HTTPDIALOGH #define HTTPDIALOGH #include #include #include #include #include #include #include #include namespace Ui { class HttpDialog; } class HttpDialog : public QDialog { Q_OBJECT public: explicit HttpDialog(QWidget *parent = 0); ~HttpDialog(); private slots: //读取服务器返回响应数据 void onFinished(QNetworkReply *reply); //验证登录密码 void onAuthenticationRequest(QNetworkReply *, QAuthenticator *); //点击链接,处理新的链接 void onAnchorClicked(const QUrl&); //接收响应数据:保存要下载的文件 void onReadyRead(); //接收响应数据完毕 void onReplyFinished(); //更新下载进度条, //参数:已经接收的数据大小/期望下载的总数据量 void updateDataReadProgress(qint64,qint64); private: //下载文件 void downloadFile(const QUrl&); private: Ui::HttpDialog *ui; QNetworkAccessManager *manager;//管理Http请求和响应 //URL(Uniform Resource Locator)统一资源定位符号 QNetworkRequest* request;//请求 QNetworkReply* reply;//响应 QUrl currentUrl;//保存当前网页的URL地址,网中每个文件都有一个独立的URL QFile *file;//保存下载的文件 }; #endif // HTTPDIALOGH // HttpDialog.cpp #include "HttpDialog.h" #include "ui_HttpDialog.h" HttpDialog::HttpDialog(QWidget *parent) : QDialog(parent), ui(new Ui::HttpDialog) { ui->setupUi(this); //构建QNetworkAccessManager对象 //用于应用程序发送网络请求和接收网络应答 manager = new QNetworkAccessManager(this); //初始化请求对象 request = new QNetworkRequest(QUrl(" http://code.tarena.com.cn/")); //向Http服务器发送请求 manager->get(*request); //隐藏文件下载进度条 ui->progressBar->hide(); //请求发送完成,收到服务器响应发送finished信号 //参数即为响应的数据对象 connect(manager,SIGNAL(finished(QNetworkReply*)), this,SLOT(onFinished(QNetworkReply*))); connect(ui->textBrowser,SIGNAL(anchorClicked(QUrl)), this,SLOT(onAnchorClicked(QUrl))); //服务器返回请求的内容之前,这个信号被发射,请求验证 //在对应的槽函数中填写密码和用户名,进行认证 connect(manager, SIGNAL(authenticationRequired(QNetworkReply *, QAuthenticator *)), this, SLOT(onAuthenticationRequest(QNetworkReply *, QAuthenticator *))); } HttpDialog::~HttpDialog() { delete ui; } void HttpDialog::onFinished(QNetworkReply *reply) { qDebug("%s",__func__); //读取服务器返回响应数据 QString replyText = reply->readAll(); //显示到文本浏览器界面 ui->textBrowser->setText(replyText); //保存当前的url currentUrl = reply->url(); } //验证登录密码 void HttpDialog::onAuthenticationRequest(QNetworkReply *, QAuthenticator *authenticator){ qDebug("%s",__func__); authenticator->setUser("tarenacode"); authenticator->setPassword("code_2013"); } //点击链接,处理新的链接 void HttpDialog::onAnchorClicked(const QUrl& url){ //qDebug() << url.toString(); //qDebug() << currentUrl.toString(); QUrl newUrl; //处理非".."的链接 if(url.toString() != "../"){ //保存当前完整的URL newUrl.setUrl(currentUrl.toString() + url.toString()); //如果是下载文件,则下载该文件 if(url.toString().indexOf(".tar.gz") != -1 || url.toString().indexOf(".txt") != -1 || url.toString().indexOf(".zip") != -1 || url.toString().indexOf(".doc") != -1 || url.toString().indexOf(".pdf") != -1 || url.toString().indexOf(".rar") != -1) { //qDebug("下载该文件..."); downloadFile(newUrl); return; } } else{//处理上一级目录".." //如果已经在顶层目录,不处理 if(currentUrl.toString() == " http://code.tarena.com.cn/"){ return; } else{//去掉最后一级目录 //http://code.tarena.com.cn/BIGCode/big1605/ //int length = currentUrl.toString().size(); //倒数第二次出现“/”的位置 int _pos = currentUrl.toString().lastIndexOf("/",-2); //截取新的字符串,去掉最后一级路径 newUrl = currentUrl.toString().mid(0,_pos+1); //qDebug() << newUrl.toString(); } } manager->get(QNetworkRequest(QUrl(newUrl))); } //下载文件 void HttpDialog::downloadFile(const QUrl& fileUrl){ qDebug() << fileUrl.toString(); //获取路径 //url.path():CSDCode/csd1603/qt/day02.tar.gz //获取要下载的文件信息:文件名 QFileInfo fileInfo(fileUrl.path()); QString fileName(fileInfo.fileName()); //创建文件 file = new QFile(fileName); if(!file->open(QIODevice::WriteOnly)) { qDebug("file open error"); delete file; file = 0; return; } //发送获取文件请求 reply = manager->get(QNetworkRequest(fileUrl)); //服务收到请求返回数据后相应对象发出readyReady信号 //onReadyRead()槽函数负责接收数据 connect(reply,SIGNAL(readyRead()),this,SLOT(onReadyRead())); //服务收到请求返回数据后也会产生downloadProgress信号 //updateDataReadProgress槽函数负责更新进度条 connect(reply,SIGNAL(downloadProgress(qint64,qint64)), this,SLOT(updateDataReadProgress(qint64,qint64))); //应答信息处理发送finished()信号,此时文件已经下载完成 connect(reply,SIGNAL(finished()), this,SLOT(onReplyFinished())); //设置显示进度条 ui->progressBar->setValue(0); ui->progressBar->show(); } //接收响应数据完毕(下载完成) void HttpDialog::onReplyFinished() { qDebug("%s",__func__); //隐藏进度条 ui->progressBar->hide(); //刷新文件缓冲区,保证数据都已经写入文件 file->flush(); //关闭文件 file->close(); //延后删除应答对象 reply->deleteLater(); reply = NULL; //删除文件指针 delete file; file = NULL; //刷新界面 QUrl newUrl; int _pos = currentUrl.toString().lastIndexOf("/"); newUrl.setUrl(currentUrl.toString().mid(0,_pos+1)); //qDebug() << newUrl.toString(); manager->get(QNetworkRequest(newUrl)); } //接收应答数据:要下载的文件 void HttpDialog::onReadyRead() { if(file){ //接收下载的数据并写到文件 file->write(reply->readAll()); } } //更新下载进度条, //参数:已经接收的数据大小/期望下载的总数据量 void HttpDialog::updateDataReadProgress(qint64 bytesRead, qint64 totalBytes) { ui->progressBar->setMaximum(totalBytes); ui->progressBar->setValue(bytesRead); } // main.cpp #include "HttpDialog.h" #include int main(int argc, char *argv[]) { QApplication a(argc, argv); HttpDialog w; w.show(); return a.exec(); }