QT實現HTTP請求(超時阻塞)
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();
}