QT实现HTTP请求(超时阻塞)

版权声明:本文为博主原创作品,转载请声明出处! https://blog.csdn.net/u011086209/article/details/84984900

postdata.hpp

#ifndef POSTDATA_HPP
#define POSTDATA_HPP

class PostData : public QObject
{
    Q_OBJECT

public:

    explicit PostData(QObject *parent = nullptr);
    ~PostData();

    /* 提交图片到PHP */
    void postImage(QString classfied, QString suffix, QByteArray image, int timeout = 3000);
    /* 提交Log到PHP */
    void postLog(QString log, int timeout = 3000);

signals:

public slots:

    void finished();

private:

    std::shared_ptr<QNetworkAccessManager> m_pManager;
    // 请求地址
    QString m_saveImgUrl = "http://localhost/SaveImg.php";
    QString m_saveLogUrl = "http://localhost/SaveLog.php";
};

postdata.cpp

#include <QUrl>
#include <QByteArray>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QHttpMultiPart>
#include <QElapsedTimer>
#include <QCoreApplication>
#include <QJsonObject>
#include <QJsonDocument>
#include <QTimer>

#include "PostData.h"

using namespace std;

PostData::PostData(QObject *parent) : QObject(parent){
    /* 实例化QNetworkAccessManager */
    m_pManager.reset(new QNetworkAccessManager);
}

PostData::~PostData(){
}

void PostData::finished(){
    QNetworkReply* reply = (QNetworkReply*) sender();
    if (!reply->isFinished()) {
        qWarning() << "post data time out";
    }
    /* 请求收到的结果 */
    QByteArray responseByte = reply->readAll();
    if (!responseByte.isEmpty()) {
        /* 错误处理 */
        if (reply->error() == QNetworkReply::NoError) {
            qWarning() << "post data success";
        } else {
            qWarning() <<"post data handle errors here";
            QVariant statusCodeV = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
            /* statusCodeV是HTTP服务器的相应码,reply->error()是Qt定义的错误码 */
            qWarning() << "status code: " << statusCodeV.toInt();
            qWarning() << "status code: " << (int)reply->error();
        }
        qWarning() << "response: " << responseByte;
    }
    disconnect(reply, &QNetworkReply::finished, this, &PostData::finished);
    reply->deleteLater();
}

void PostData::postImage(QString classfied, QString suffix, QByteArray image, int timeout){

    QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);

    /* 部件图片类别 */
    QHttpPart dataPart;
    dataPart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("text/plain"));
    dataPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"data\""));
    QJsonObject data;
    data.insert("type", classfied);
    data.insert("suffix", suffix);
    data.insert("image", QString(image));
    QByteArray imageInfo = QJsonDocument(data).toJson();
    dataPart.setBody(imageInfo);
    multiPart->append(dataPart);

    /* 设置头信息 */
    QNetworkRequest requestInfo;
    requestInfo.setUrl(QUrl(m_saveImgUrl));

    /* 发送数据 */
    QNetworkReply *reply = m_pManager->post(requestInfo, multiPart);
    multiPart->setParent(reply);

    /* 超时定时器 */
    QElapsedTimer timer;
    timer.start();
    connect(reply, SIGNAL(finished()), this, SLOT(finished()));

    if (timeout < 0) {
        qWarning() << "timeout is error";
        return;
    }

    /* 处理响应 */
    while (timer.elapsed() < timeout) {
        QCoreApplication::processEvents();
    }
}

void PostData::postLog(QString log, int timeout){

    /* 设置头信息 */
    QNetworkRequest requestInfo;
    requestInfo.setUrl(QUrl(m_networkUrl));
    requestInfo.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
    QByteArray logInfo = QString(log).toUtf8();

    /* 发送数据 */
    QNetworkReply *reply = m_pManager->post(requestInfo, "log=" + logInfo);

    /* 添加事件循环机制,返回后再运行后面的 */
    QEventLoop eventLoop;
    connect(reply, SIGNAL(finished()), &eventLoop, SLOT(quit()));
   QTimer timer;
    timer.setInterval(timeout);
    timer.setSingleShot(true);
    timer.start();
    eventLoop.exec();

    /* 处理响应 */
    if (timer.isActive()) {
        /* 错误处理 */
        if (reply->error() == QNetworkReply::NoError) {
            qWarning() << "request protobufHttp success";
        } else {
            qWarning() <<"request protobufHttp handle errors here";
            QVariant statusCodeV = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
            /* statusCodeV是HTTP服务器的相应码,reply->error()是Qt定义的错误码,可以参考QT的文档 */
            qWarning() << "status code: " << statusCodeV.toInt();
            qWarning() << "status code: " << (int)reply->error();
        }
        /* 请求收到的结果 */
        QByteArray responseByte = reply->readAll();
        qWarning() << "response: " << responseByte;
    } else {
        disconnect(reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
        reply->abort();
        qWarning() << "time out";
    }
    reply->deleteLater();
}

main.cpp

#include <QCoreApplication>
#include <QDebug>
#include <PostData.h>
#include <QByteArray>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    /* 调用post请求接口 */
    PostData manager;
    //QByteArray data = QByteArray::fromBase64("PHA+SGVsbG8/PC9wPg==", QByteArray::Base64Encoding);
    //manager.postImage("module", "jpg", data);
    //manager.postImage("module", "jpg", data, -1);
    //manager.postLog("log");
    manager.postLog("log",  5000);

    return a.exec();
}

猜你喜欢

转载自blog.csdn.net/u011086209/article/details/84984900