Qt文档阅读笔记-QNetworkAccessManager官方解析与实例

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq78442761/article/details/86717926

目录

 

官方解析

博主例子


官方解析

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<QSslError>)),
          this, SLOT(slotSslErrors(QList<QSslError>)));

博主例子

现在举一个下载http网站中web主页的例子,注意了是http的协议,不是https的协议!!!

程序运行截图如下:

程序结构如下:

源码如下:

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

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 <QApplication>

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 <QNetworkAccessManager>
#include <QNetworkReply>
#include <QDebug>
#include <QNetworkReply>

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 <QNetworkAccessManager>
#include <QNetworkReply>
#include <QDebug>
#include <QNetworkReply>

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()));

}

包头如下:

猜你喜欢

转载自blog.csdn.net/qq78442761/article/details/86717926