[Qt教程] 第32篇 网络(二)HTTP

[Qt教程] 第32篇
网络(二)HTTP

楼主

 发表于 2013-8-28 17:21:28 | 查看:
637| 回复: 8


HTTP

版权声明


该文章原创于作者yafeilinux,转载请注明出处!

导语


       
HTTP(HyperText Transfer Protocol,超文本传输协议)是一个客户端和服务器端请求和应答的标准。在Qt的网络模块中提供了网络访问接口来实现HTTP编程。网络访问接口是执行一般的网络操作的类的集合,该接口在特定的操作和使用的协议(例如,通过HTTP进行获取和发送数据)上提供了一个抽象层,只为外部暴露出了类、函数和信号。

上一节中我们已经提到过了,现在Qt中使用QNetworkAccessManager类和QNetworkReply类来进行HTTP的编程。网络请求由QNetworkRequest类来表示,它也作为与请求有关的信息(例如,任何头信息和使用加密)的容器。在创建请求对象时指定的URL决定了请求使用的协议,目前支持HTTP、FTP和本地文件URLs的上传和下载。QNetworkAccessManager类用来协调网络操作,每当一个请求创建后,该类用来调度它,并发射信号来报告进度。该类还协调cookies的使用,身份验证请求,及其代理的使用等。对于网络请求的应答使用QNetworkReply类表示,它会在请求被完成调度时由QNetworkAccessManager来创建。QNetworkReply提供的信号可以用来单独的监视每一个应答。

       下面我们先讲解一个简单下载网页的例子,然后将其扩展为可以下载任何文件。

环境:Windows Xp + Qt 4.8.5+Qt Creator 2.8.0

目录


一、简单的网页浏览功能

二、实现下载文件功能

正文


一、简单的网页浏览功能

1.新建Qt Gui应用,项目名称为http,基类使用默认的QMainWindow即可,类名为MainWindow。

2.完成后打开http.pro文件,然后添加下面一行代码来使用网络模块:

QT  += network

       然后保存该文件。

3.下面打开mainwindow.ui文件进入设计模式,向界面上添加一个Text Browser部件。效果如下图所示。

4.打开mainwindow.h文件,先包含头文件:#include <QtNetwork>

然后添加一个private私有对象定义:QNetworkAccessManager
*manager;

最后添加一个私有槽声明:

private slots:

    void replyFinished(QNetworkReply *);

5.下面到mainwindow.cpp文件中,先在构造函数中添加如下代码:

manager = new QNetworkAccessManager(this);

connect(manager, SIGNAL(finished(QNetworkReply*)),

this,SLOT(replyFinished(QNetworkReply*)));

manager->get(QNetworkRequest(QUrl("http://www.qter.org")));

这里先创建了一个QNetworkAccessManager类的实例,它用来发送网络请求和接收应答。然后关联了管理器的finished()信号和我们自定义的槽,每当网络应答结束时都会发射这个信号。最后使用了get()函数来发送一个网络请求,网络请求使用QNetworkRequest类表示,get()函数返回一个QNetworkReply对象。除了get()函数,管理器还提供了发送HTTP
POST请求的post()函数。

6.下面添加槽的定义:

void MainWindow::replyFinished(QNetworkReply *reply)

{

    QTextCodec *codec = QTextCodec::codecForName("utf8");

    QString all = codec->toUnicode(reply->readAll());

    ui->textBrowser->setText(all);

    reply->deleteLater();

}

因为QNetworkReply继承自QIODevice类,所以可以操作一般的I/O设备一样来操作该类。这里使用了readAll()函数来读取所有的应答数据,为了正常显示中文,使用了QTextCodec类来转换编码。在完成数据的读取后,需要使用deleteLater()来删除replay对象。

7.因为这里使用了QtextCodec类,所以还需要在mainwindow.cpp文件中包含头文件

#include <QTextCodec>

       下面运行程序,效果如下图所示。

       
这里再将整个过程简答叙述一遍:上面实现了最简单的应用HTTP协议下载网页的功能。QNetworkAccessManager类用于发送网络请求和接受回复,具体来说,它是用QNetworkRequest 类来管理请求,QNetworkReply类进行接收回复,并对数据进行处理。

在上面的代码中,我们使用了下面的代码来发送请求:

manager->get(QNetworkRequest(QUrl("http://www.qter.org")));

它返回一个QNetworkReply对象,这个后面再讲。我们只需知道只要发送请求成功,它就会下载数据。而当数据下载完成后,manager会发出finished()信号,我们关联了该信号:

connect(manager, SIGNAL(finished(QNetworkReply*)),

this,SLOT(replyFinished(QNetworkReply*)));

也就是说,当下载数据结束时,就会执行replyFinished()函数。在这个函数中我们对接收的数据进行处理:

QTextCodec *codec = QTextCodec::codecForName("utf8");

QString all = codec->toUnicode(reply->readAll());

ui->textBrowser->setText(all);

这里,为了能显示下载的网页中的中文,我们使用了QTextCodec 类对象,应用utf8编码。使用reply->readAll()函数就可以将下载的所有数据读出。然后,我们在textBrowser中将数据显示出来。当reply对象已经完成了它的功能时,我们需要将它释放,就是最后一条代码:

reply->deleteLater();

二、实现下载文件功能

       
通过上面的例子可以看到,Qt中编写基于HTTP协议的程序是十分简单的,只有十几行代码。不过,一般我们下载文件都想要看到下载进度。下面我们就更改上面的程序,让它可以下载任意的文件,并且显示下载进度。

1.进入设计模式,删除以前的Text Browser部件,然后拖入一个Line Edit,一个Label,一个Progress
Bar和一个Push Button,设计界面如下图所示。

2. 在写代码之前,我们先介绍一下整个程序执行的流程:开始我们先让进度条隐藏。当我们在Line Edit中输入下载地址,点击下载按钮后,我们应用输入的下载地址,获得文件名,在磁盘上新建一个文件,用于保存下载的数据,然后进行链接,并显示进度条。在下载过程中,我们将每次获得的数据都写入文件中,并更新进度条,在接收完文件后,我们重新隐藏进度条,并做一些清理工作。根据这个思路,我们开始代码的编写。

3.到mainwindow.h中,首先添加public函数声明:

void startRequest(QUrl url); //请求链接

然后添加几个private变量和对象定义:

QNetworkReply *reply;

QUrl url;   //存储网络地址

QFile *file;  //文件指针

最后到private slots中,删除前面的replyFinished(QNetworkReply *)槽声明,并添加如下代码:

private slots:

    void on_pushButton_clicked();  //下载按钮的单击事件槽函数

    void httpFinished();  //完成下载后的处理

    void httpReadyRead();  //接收到数据时的处理

    void updateDataReadProgress(qint64, qint64); //更新进度条

4. 下面到mainwindow.cpp文件中,将前面在构造函数中添加的内容删除,然后添加如下代码:

manager = new QNetworkAccessManager(this);  

ui->progressBar->hide();

我们在构造函数中先隐藏进度条。等开始下载时再显示它。

5. 下面将前面程序中添加的replyFinished()函数的定义删除,然后添加新的函数的定义。先添加网络请求函数的实现:

void MainWindow::startRequest(QUrl url)

{

    reply = manager->get(QNetworkRequest(url));

    connect(reply, SIGNAL(readyRead()), this, SLOT(httpReadyRead()));

    connect(reply, SIGNAL(downloadProgress(qint64, qint64)),

            this, SLOT(updateDataReadProgress(qint64, qint64)));

    connect(reply, SIGNAL(finished()), this, SLOT(httpFinished()));

}

这里使用了get()函数来发送网络请求,然后进行了QNetworkReply对象的几个信号和自定义槽的关联。其中readyRead()信号继承自QIODevice类,每当有新的数据可以读取时,都会发射该信号;每当网络请求的下载进度更新时都会发射downloadProgress()信号,它用来更新进度条;每当应答处理结束时,都会发射finished()信号,该信号与前面程序中QNetworkAccessManager类的finished()信号作用相同,只不过是发送者不同,参数也不同而已。下面添加几个槽的定义。

void MainWindow::httpReadyRead()

{

    if (file) file->write(reply->readAll());

}

这里先判断是否创建了文件,如果是,则读取返回的所有数据,然后写入到文件。该文件是在后面的“下载”按钮单击信号槽中创建并打开的。

void MainWindow::updateDataReadProgress(qint64 bytesRead, qint64 totalBytes)

{

    ui->progressBar->setMaximum(totalBytes);

    ui->progressBar->setValue(bytesRead);

}

        
这里设置了一下进度条的最大值和当前值。

void MainWindow::httpFinished()

{

    ui->progressBar->hide();

    file->flush();

    file->close();

    reply->deleteLater();

    reply = 0;

    delete file;

    file = 0;

}

        
当完成下载后,重新隐藏进度条,然后删除reply和file对象。下面是“下载”按钮的单击信号的槽:

void MainWindow::on_pushButton_clicked()

{

    url = ui->lineEdit->text();

    QFileInfo info(url.path());

    QString fileName(info.fileName());

    if (fileName.isEmpty()) fileName = "index.html";

    file = new QFile(fileName);

    if(!file->open(QIODevice::WriteOnly))

    {

        qDebug() << "file open error";

        delete file;

        file = 0;

        return;

    }

    startRequest(url);

    ui->progressBar->setValue(0);

    ui->progressBar->show();

}

这里使用要下载的文件名创建了本地文件,然后使用输入的url进行了网络请求,并显示进度条。

6.下面运行程序,我们先输入www.yafeilinux.com的网址,下面一个网页。效果如下图所示。

 

完成后,可以尝试输入一个文件的下载地址,比如这里输入了《Qt Creator快速入门》一书在百度网盘上的地址,效果如下图所示。

7.最后,可以去项目编译生成的文件目录中查看下载的文件(我这里是E:\http-build-桌面-Debug),可以看到下载的文件,如下图所示。

结语


HTTP应用的内容就讲到这里,可以看到它是很容易的,也不需要大家了解太多的HTTP的原理知识。关于相关的类的其他使用,也可以查看其帮助文档。在上面的例子中,我们只是为了讲解知识,所以程序不是很完善,对于一个真正的工程,还是需要注意更多其他细节的,大家可以查看一下Qt演示程序HTTP
Client的源代码。



涉及到的源码:  http.zip (2.89
KB, 下载次数: 14) 
时间: 2025-01-02 04:57:39

[Qt教程] 第32篇 网络(二)HTTP的相关文章

[Qt教程] 第34篇 网络(四)FTP(二)

[Qt教程] 第34篇 网络(四)FTP(二) 楼主  发表于 2013-9-4 15:04:38 | 查看: 315| 回复: 9 FTP(二) 版权声明 该文章原创于作者yafeilinux,转载请注明出处! 导语 前面讲述了一个最简单的FTP客户端程序的编写,这一节我们将这个程序进行扩展,使其可以浏览并能下载服务器上的所有文件. 环境:Windows Xp + Qt 4.8.5+QtCreator 2.8.0 目录 一.修改界面 二.功能实现 正文 一.修改界面 我们删除了TextBrow

[Qt教程] 第38篇 网络(八)TCP(二)

[Qt教程] 第38篇 网络(八)TCP(二) 楼主  发表于 2013-9-6 15:50:35 | 查看: 421| 回复: 3 TCP(二) 版权声明 该文章原创于作者yafeilinux,转载请注明出处! 导语 在上一节里我们使用TCP服务器发送一个字符串,然后在TCP客户端进行接收.在这一节将重新写一个客户端程序和一个服务器程序,这次实现客户端进行文件的发送,服务器进行文件的接收.有了上一节的基础,这一节的内容就很好理解了,注意一下几个信号和槽的关联即可.当然,我们这次要更深入了解一下

[Qt教程] 第35篇 网络(五)获取本机网络信息

[Qt教程] 第35篇 网络(五)获取本机网络信息 楼主  发表于 2013-9-5 11:32:58 | 查看: 278| 回复: 2 获取本机网络信息 版权声明 该文章原创于作者yafeilinux,转载请注明出处! 导语 前面讲完了HTTP和FTP,下面本来该讲解UDP和TCP了.不过,在讲解它们之前,我们先在这一节里讲解一个以后要经常用到的名词,那就是IP地址.        对于IP地址,其实,会上网的人都应该听说过它.如果你实在很不属性,那么简单的说:IP即InternetProto

[Qt教程] 第31篇 网络(一)Qt网络编程简介

[Qt教程] 第31篇 网络(一)Qt网络编程简介 楼主  发表于 2013-8-28 17:04:17 | 查看: 515| 回复: 0 Qt网络编程简介 版权声明 该文章原创于作者yafeilinux,转载请注明出处! 导语 从这一节开始我们讲述Qt网络应用方面的编程知识.在开始这部分知识的学习之前,大家最好已经拥有了一定的网络知识和Qt的编程基础.在后面的教程中我们不会对一个常用的网络名词进行详细的解释,对于不太了解的地方,大家可以参考相关书籍. 不过,大家也没有必要非得先去学习网络专业知

[Qt教程] 第33篇 网络(三)FTP(一)

[Qt教程] 第33篇 网络(三)FTP(一) 楼主  发表于 2013-9-4 14:52:46 | 查看: 392| 回复: 8 FTP(一) 版权声明 该文章原创于作者yafeilinux,转载请注明出处! 导语 上一节我们讲述了HTTP的编程,这一节讲述与其及其相似的FTP的编程.FTP即FileTransfer Protocol,也就是文件传输协议.FTP的主要作用,就是让用户连接上一个远程计算机,查看远程计算机有哪些文件,然后把文件从远程计算机上拷贝到本地计算机,或者把本地计算机的文

[Qt教程] 第36篇 网络(六)UDP

[Qt教程] 第36篇 网络(六)UDP 楼主  发表于 2013-9-5 11:38:50 | 查看: 241| 回复: 0 UDP 版权声明 该文章原创作者yafeilinux,转载请注明出处! 导语 这一节讲述UDP编程的知识.UDP(UserDatagram Protocol即用户数据报协议)是一个轻量级的,不可靠的,面向数据报的无连接协议.对于UDP我们不再进行过多介绍,如果你对UDP不是很了解,而且不知道它有什么用,那么这里就举个简单的例子:我们现在几乎每个人都使用的腾讯QQ,其聊天

[Qt教程] 第40篇 网络(十)WebKit初识

[Qt教程] 第40篇 网络(十)WebKit初识 楼主  发表于 2013-9-11 17:26:05 | 查看: 521| 回复: 10 WebKit初识 版权声明 该文章原创于作者yafeilinux,转载请注明出处! 导语 WebKit是一个开源的浏览器引擎.Qt中提供了基于WebKit的QtWebKit模块,它包含了一组相关的类.QtWebKit提供了一个Web浏览器引擎,使用它便可以很容易的将万维网(WorldWide Web)中的内容嵌入到Qt应用程序中.与此同时,本地也可以对We

[Qt教程] 第39篇 网络(九)进程和线程

[Qt教程] 第39篇 网络(九)进程和线程 楼主  发表于 2013-8-29 15:48:56 | 查看: 415| 回复: 0 进程和线程 版权声明 该文章原创于作者yafeilinux,转载请注明出处! 导语 在前面的几节内容中讲解了Qt网络编程的一些基本内容,这一节来看一下在Qt中进程和线程的基本应用. 环境:Windows Xp + Qt 4.8.5+Qt Creator2.8.0 目录 一.进程 二.线程 正文 一.进程     在设计一个应用程序时,有时不希望将一个不太相关的功能

[Qt教程] 第37篇 网络(七)TCP(一)

[Qt教程] 第37篇 网络(七)TCP(一) 楼主  发表于 2013-9-6 15:44:45 | 查看: 398| 回复: 1 TCP (一) 版权声明 该文章原创于作者yafeilinux,转载请注明出处! 导语 TCP即TransmissionControl Protocol,传输控制协议.与UDP不同,它是面向连接和数据流的可靠传输协议.也就是说,它能使一台计算机上的数据无差错的发往网络上的其他计算机,所以当要传输大量数据时,我们选用TCP协议.         TCP协议的程序使用