QT:HTTP协议简单应用

HTTP协议

QNetworkAccessManager
QNetworkReply

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

/* HTTP文本浏览器 - 代码演示 */

// HttpDialog.h
#ifndef HTTPDIALOGH
#define HTTPDIALOGH
#include <QDialog>
#include <QNetworkAccessManager >
#include <QUrl >
#include <QNetworkRequest >
#include <QNetworkReply >
#include <QAuthenticator >
#include <QFile >
#include <QFileInfo >
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 <QApplication>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    HttpDialog w;
    w.show();
    return a.exec();
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

姜源Jerry

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值