目录
官方解析
博主例子
QNetworkAccessMangager类运行应用程序回复和接收网络包。
QNetworkAccessManager是一套API库,可以发包,设置代理,内存配置等。可以用于网络的应答(如http协议)。
如下面这个伪代码的栗子:
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
connect(manager, SIGNAL(finished(QNetworkReply*)),
this, SLOT(replyFinished(QNetworkReply*)));
manager->get(QNetworkRequest(QUrl("http://qt-project.org")));
注意:这是一个异步的API。
当请求完成后,用户需要手动删除QNetworkReply对象,这里要注意,不应该在finished()信号过来的时候删除,而应该使用deleteLater()函数。
如果要并行处理,这里取决于平台,目前桌面平台支持6个并行。
如下面这个设置User-Agent的栗子:
QNetworkRequest request;
request.setUrl(QUrl("http://qt-project.org"));
request.setRawHeader("User-Agent", "MyOwnBrowser 1.0");
QNetworkReply *reply = manager->get(request);
connect(reply, SIGNAL(readyRead()), this, SLOT(slotReadyRead()));
connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
this, SLOT(slotError(QNetworkReply::NetworkError)));
connect(reply, SIGNAL(sslErrors(QList)),
this, SLOT(slotSslErrors(QList)));
现在举一个下载http网站中web主页的例子,注意了是http的协议,不是https的协议!!!
程序运行截图如下:
程序结构如下:
源码如下:
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include
QT_BEGIN_NAMESPACE
class QNetworkAccessManager;
class QNetworkReply;
QT_END_NAMESPACE
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
protected slots:
void replyFinished(QNetworkReply *reply);
void netWorkReplyLoadProgress(qint64 received, qint64 total);
void deleteNetWorkReply();
private:
Ui::Widget *ui;
QNetworkAccessManager *m_manager;
QNetworkReply *m_netWorkReply;
};
#endif // WIDGET_H
main.cpp
#include "widget.h"
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include
#include
#include
#include
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
m_manager = new QNetworkAccessManager(this);
connect(m_manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
QUrl url("http://www.it1995.cn/");
m_netWorkReply = m_manager->get(QNetworkRequest(url));
connect(m_netWorkReply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(netWorkReplyLoadProgress(qint64,qint64)));
}
Widget::~Widget()
{
delete ui;
}
void Widget::replyFinished(QNetworkReply *reply)
{
qDebug() << "replyFinished called!";
qDebug() << "reply->readAll():" << QString::fromUtf8(reply->readAll());
m_netWorkReply->deleteLater(); //此列子中 m_netWorkReply->deleteLater(); 与 delete m_netWorkReply; 没有什么区别
}
void Widget::netWorkReplyLoadProgress(qint64 received, qint64 total)
{
qDebug() << "received:" << received << " total:" << total;
}
void Widget::deleteNetWorkReply()
{
qDebug() << "deleteNetWorkReply called!" << endl;
}
此处可以提升一下,在replyFinished这个函数里面,如果要把网页保存,那些这么做会,这个函数占用大量的CUP和内存(如果此处并行保存6个100MB的文件),在这里可以在QNetworkReply类中的readyRead这个信号关联后进行,因为网络传输数据太大,会被拆分,如下所示:
本例子下载的网页比较小,现象不明显,
把widget.cpp改成如下就明显了:
#include "widget.h"
#include "ui_widget.h"
#include
#include
#include
#include
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
m_manager = new QNetworkAccessManager(this);
connect(m_manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
QUrl url("http://www.it1995.cn/");
m_netWorkReply = m_manager->get(QNetworkRequest(url));
connect(m_netWorkReply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(netWorkReplyLoadProgress(qint64,qint64)));
connect(m_netWorkReply, SIGNAL(readyRead()), this, SLOT(httpRead()));
}
Widget::~Widget()
{
delete ui;
}
void Widget::replyFinished(QNetworkReply *reply)
{
qDebug() << "replyFinished called!";
//qDebug() << "reply->readAll():" << QString::fromUtf8(reply->readAll());
m_netWorkReply->deleteLater(); //此列子中 m_netWorkReply->deleteLater(); 与 delete m_netWorkReply; 没有什么区别
}
void Widget::netWorkReplyLoadProgress(qint64 received, qint64 total)
{
qDebug() << "received:" << received << " total:" << total;
}
void Widget::deleteNetWorkReply()
{
qDebug() << "deleteNetWorkReply called!" << endl;
}
void Widget::httpRead()
{
qDebug() << "111";
}
运行截图如下:
此处把httpRead()修改如下,再看看运行结果:
void Widget::httpRead()
{
qDebug() << m_netWorkReply->readAll();
}
运行截图和最开始的一样,可以用这个思路去保存文件!减少内存和CPU的使用!
这里来看看此时发送的Http数据包头:
修改源码,生成User-Agent属性,
添加这几行行即可:
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
m_manager = new QNetworkAccessManager(this);
connect(m_manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
QNetworkRequest request;
request.setUrl(QUrl("http://www.it1995.cn/"));
request.setRawHeader("User-Agent", "I am fine, fuck you");
m_netWorkReply = m_manager->get(request);
connect(m_netWorkReply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(netWorkReplyLoadProgress(qint64,qint64)));
connect(m_netWorkReply, SIGNAL(readyRead()), this, SLOT(httpRead()));
}
包头如下: