Qt利用QNetwork實(shí)現(xiàn)上傳數(shù)據(jù)的示例代碼
更新時(shí)間:2023年02月24日 08:32:50 作者:歐特克_Glodon
這篇文章主要為大家詳細(xì)介紹了Qt如何利用QNetwork實(shí)現(xiàn)上傳數(shù)據(jù)的 功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
1、利用Qt提供的類實(shí)現(xiàn)向服務(wù)器發(fā)送post和get請(qǐng)求
#include <QCoreApplication>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonParseError>
#include <QJsonValue>
#include <QString>
#include <QDebug>
#include <QFile>
#include <QDateTime>
#include <QDir>
#include <QThread>
#pragma execution_character_set("utf-8")
void sendPostRequest()
{
QNetworkAccessManager *m_pHttpMgr = new QNetworkAccessManager();
//設(shè)置url
QString url = "http://localhost:80/post";
//設(shè)置頭信息
QNetworkRequest requestInfo;
requestInfo.setUrl(QUrl(url));
requestInfo.setHeader(QNetworkRequest::ContentTypeHeader,QVariant("application/json"));
//requestInfo.setRawHeader("Content-Type","application/json");//服務(wù)器要求的數(shù)據(jù)頭部
//requestInfo.setRawHeader("Accept","text/json,*/*;q=0.5");//服務(wù)器要求的數(shù)據(jù)頭部
//發(fā)送數(shù)據(jù)
QJsonObject regionObject;
regionObject.insert("name","333");
regionObject.insert("height", "2");
regionObject.insert("dir", "0");
QJsonArray pointAry;
pointAry.append(0.8);
pointAry.append(1.0);
pointAry.append(0.0);
pointAry.append(1.8);
pointAry.append(2.0);
pointAry.append(0.0);
regionObject.insert("points", QJsonValue(pointAry));
QJsonObject jsonObject;
jsonObject.insert("Code", "asss");
jsonObject.insert("parentId", 0);
jsonObject.insert("depot", "past");
jsonObject.insert("region", QJsonValue(regionObject));
QJsonDocument jsonDoc;
jsonDoc.setObject(jsonObject);
QByteArray qByteHttpData = jsonDoc.toJson();
QNetworkReply *reply = m_pHttpMgr->post(requestInfo, qByteHttpData);
//添加事件循環(huán)機(jī)制,返回后再運(yùn)行后面的
QEventLoop eventLoop;
QObject::connect(reply, SIGNAL(finished()), &eventLoop, SLOT(quit()));
eventLoop.exec(); //block until finish
//錯(cuò)誤處理
if (reply->error() != QNetworkReply::NoError)
{
qDebug()<<"request protobufHttp handle errors here";
QVariant statusCodeV = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
//statusCodeV是HTTP服務(wù)器的相應(yīng)碼,reply->error()是Qt定義的錯(cuò)誤碼,可以參考QT的文檔
qDebug( "request protobufHttp found error ....code: %d %d\n", statusCodeV.toInt(), (int)reply->error());
qDebug(qPrintable(reply->errorString()));
}
//請(qǐng)求收到的結(jié)果
QByteArray responseByte = reply->readAll();
QString strRes = responseByte;
qDebug() << "Post:" << strRes;
}
void sendGetRequest()
{
QNetworkAccessManager *m_pHttpMgr = new QNetworkAccessManager();
//設(shè)置url
QString url = "http://localhost:80/Get;
QNetworkRequest requestInfo;
requestInfo.setUrl(QUrl(url));
//添加事件循環(huán)機(jī)制,返回后再運(yùn)行后面的
QEventLoop eventLoop;
QNetworkReply *reply = m_pHttpMgr->get(requestInfo);
QObject::connect(reply, SIGNAL(finished()), &eventLoop, SLOT(quit()));
eventLoop.exec(); //block until finish
//錯(cuò)誤處理
if (reply->error() != QNetworkReply::NoError)
{
qDebug()<<"request protobufHttp handle errors here";
QVariant statusCodeV = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
//statusCodeV是HTTP服務(wù)器的相應(yīng)碼,reply->error()是Qt定義的錯(cuò)誤碼,可以參考QT的文檔
qDebug( "request protobufHttp found error ....code: %d %d\n", statusCodeV.toInt(), (int)reply->error());
qDebug(qPrintable(reply->errorString()));
}
//請(qǐng)求返回的結(jié)果
QByteArray responseByte = reply->readAll();
QString strRes = responseByte;
qDebug() << "Get:" << strRes;
QFile file(QDir::currentPath() + "/myResponde.json");
if(!file.open(QIODevice::ReadWrite))
{
qDebug() << "File open error";
}
file.write(responseByte);
file.close();
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
sendPostRequest();
//sendGetRequest();
return a.exec();
}
2、實(shí)現(xiàn)文件上傳
QT += core gui QT += network greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++11
Qnetworkutils.h 頭文件
#ifndef QNETWORKUTILS_H
#define QNETWORKUTILS_H
#include <iostream>
#include <QString>
#include <QNetworkRequest>
using namespace std;
namespace QNetWorkUtils
{
// http請(qǐng)求數(shù)據(jù)
struct HttpRequestData
{
HttpRequestData()
{
strServer = "127.0.0.1";
nPort = 8082;
strUrl = "";
}
// 重置數(shù)據(jù)
void Reset()
{
strServer = "127.0.0.1";
nPort = 8082;
strUrl = "";
bytePostData.clear();
mapHeaders.clear();
}
QString strServer;
int nPort;
QString strUrl;
QByteArray bytePostData;
std::map<QNetworkRequest::KnownHeaders, QVariant> mapHeaders;
};
class CMultiPartItem
{
public:
CMultiPartItem();
// 該part為一個(gè)字符串,可以指定ContentType和ExContentDisposition
CMultiPartItem(const QString& strName, const QString& strValue,
const QString& strContentType = "",
const QString& strExContentDisposition = "");
// 該part為一個(gè)二進(jìn)制塊,可以指定ContentType(如“image/png”,可省略)和ExContentDisposition(如“filename="123.png"”,必須)
CMultiPartItem(const QString& strName, void* pData, int nLen,
const QString& strContentType = "",
const QString& strExContentDisposition = "");
QString m_sName;
QString m_sValue;
void* m_pData;
int m_nDataLen;
QString m_sContentType;
QString m_sExContentDisposition;
};
typedef std::vector<CMultiPartItem> CMultiPartDatas;
//************************************
// 方法: 發(fā)送Get請(qǐng)求
// 返回值: bool
// 參數(shù): const HttpRequestData & data 請(qǐng)求數(shù)據(jù)
// 參數(shù): QByteArray & respData 返回響應(yīng)數(shù)據(jù)
// 參數(shù): int nTimeoutmsec 請(qǐng)求超時(shí)毫秒
//************************************
bool HttpGet(
const HttpRequestData& data,
QByteArray& respData,
int nTimeoutmsec = 30000,
QString errMsg = QString(),
int* pStatuCode = nullptr);
//************************************
// 方法: 發(fā)送Post請(qǐng)求
// 返回值: bool
// 參數(shù): const HttpRequestData & data 請(qǐng)求數(shù)據(jù)
// 參數(shù): QByteArray & respData 返回響應(yīng)數(shù)據(jù)
// 參數(shù): int nTimeoutmsec 請(qǐng)求超時(shí)毫秒
//************************************
bool HttpPost(const HttpRequestData& data,
QByteArray& respData,
QString& errMsg,
int nTimeoutmsec = 30000);
//************************************
// 方法: Multipart 數(shù)據(jù)post上傳
// 返回值: bool
// 參數(shù): const QString& strURL 請(qǐng)求URL
// 參數(shù): const CMultiPartDatas& multiPartDatas 多部數(shù)據(jù)集合
// 參數(shù): QByteArray & respData 返回響應(yīng)數(shù)據(jù)
// 參數(shù): int nTimeoutmsec
bool UploadMultipartData(
const QString& strURL,
const CMultiPartDatas& multiPartDatas,
QByteArray& respData,
QString& errMsg,
int nTimeoutmsec = 30000);
bool UploadMultipartData(
const HttpRequestData& data,
const CMultiPartDatas& multiPartDatas,
QByteArray& respData,
QString& errMsg,
int nTimeoutmsec = 30000);
}
#endif // QNETWORKUTILS_H
Qnetworkutils.cpp 源文件
#include "networkutils.h"
#include <QNetworkRequest>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QHttpMultiPart>
#include <QEventLoop>
#include <QTimer>
namespace QNetWorkUtils
{
CMultiPartItem::CMultiPartItem() :
m_pData(nullptr),
m_nDataLen(0)
{
}
CMultiPartItem::CMultiPartItem(const QString& strName, const QString& strValue,
const QString& strContentType /*= ""*/, const QString& strExContentDisposition /*= ""*/)
{
m_pData = nullptr;
m_nDataLen = 0;
m_sName = strName;
m_sValue = strValue;
m_sContentType = strContentType;
m_sExContentDisposition = strExContentDisposition;
}
CMultiPartItem::CMultiPartItem(const QString& strName, void* pData, int nLen,
const QString& strContentType /*= ""*/, const QString& strExContentDisposition /*= ""*/)
{
m_pData = pData;
m_nDataLen = nLen;
m_sName = strName;
m_sContentType = strContentType;
m_sExContentDisposition = strExContentDisposition;
}
//
bool HttpGet(
const HttpRequestData& data,
QByteArray& respData,
int nTimeoutmsec /*= 30000*/,
QString& errMsg,
int* pStatuCode /*= nullptr*/)
{
// Assemble Url
QString strUrl = data.strUrl;
if (!data.strServer.isEmpty())
strUrl = data.strServer + ":" + QString::number(data.nPort) + "/" + data.strUrl;
const QUrl url = QUrl::fromUserInput(strUrl);
// Send Get Requeset
QNetworkRequest request(url);
for (auto iter = data.mapHeaders.begin(); iter != data.mapHeaders.end(); iter++)
{
request.setHeader(iter->first, iter->second);
}
QNetworkAccessManager qNetAccessManager;
QNetworkReply* reply = qNetAccessManager.get(request);
if (reply == nullptr)
return false;
// Set time out
QTimer timer;
timer.setInterval(nTimeoutmsec); // 設(shè)置超時(shí)時(shí)間 30 秒
timer.setSingleShot(true); // 單次觸發(fā)
// Set Loop Event
QEventLoop eventLoop;
QObject::connect(&timer, &QTimer::timeout, &eventLoop, &QEventLoop::quit);
QObject::connect(reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
timer.start();
int eRes = eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
bool bResult = false;
if (timer.isActive())
{
timer.stop();
QNetworkReply::NetworkError replyError = reply->error();
QVariant variant = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
int nStatusCode = variant.toInt();
if (nullptr != pStatuCode)
{
*pStatuCode = nStatusCode;
}
if (replyError != QNetworkReply::NoError)
{
errMsg = reply->errorString();
qDebug() << "Error String : " << errMsg << "\n";
}
else
{
if (nStatusCode == 200)
{
// Accept Response
respData = reply->readAll();
bResult = true;
}
else
{
bResult = false;
}
}
}
else
{
QObject::disconnect(reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
reply->abort();
qDebug() << strUrl << ":Timeout\n";
}
reply->deleteLater();
reply = nullptr;
return bResult;
}
bool HttpPost(const HttpRequestData &data, QByteArray &respData, QString &errMsg, int nTimeoutmsec)
{
// Assemble Url
QString strUrl = data.strUrl;
if (!data.strServer.isEmpty())
strUrl = data.strServer + ":" + QString::number(data.nPort) + "/" + data.strUrl;
const QUrl url = QUrl::fromUserInput(strUrl);
// Send Post Requeset
QNetworkRequest request(url);
for (auto iter = data.mapHeaders.begin(); iter != data.mapHeaders.end(); iter++)
{
request.setHeader(iter->first, iter->second);
}
QNetworkAccessManager qNetAccessManager;
QNetworkReply* reply = qNetAccessManager.post(request, data.bytePostData);
if (reply == nullptr)
return false;
// Set time out
QTimer timer;
timer.setInterval(nTimeoutmsec); // 設(shè)置超時(shí)時(shí)間 30 秒
timer.setSingleShot(true); // 單次觸發(fā)
// Set Loop Event
QEventLoop eventLoop;
QObject::connect(&timer, &QTimer::timeout, &eventLoop, &QEventLoop::quit);
QObject::connect(reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
timer.start();
eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
bool bResult = false;
if (timer.isActive())
{
timer.stop();
QNetworkReply::NetworkError replyError = reply->error();
if (replyError != QNetworkReply::NoError)
{
errMsg = reply->errorString();
qDebug() << "Error String : " << reply->errorString() << "\n";
}
else
{
QVariant variant = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
int nStatusCode = variant.toInt();
if (nStatusCode == 200)
{
// Accept Response
respData = reply->readAll();
bResult = true;
}
}
}
else
{
QObject::disconnect(reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
reply->abort();
errMsg = (strUrl + ":Timeout\n");
qDebug() << strUrl << ":Timeout\n";
}
reply->deleteLater();
reply = nullptr;
return bResult;
}
bool UploadMultipartData(const HttpRequestData &data, const CMultiPartDatas &multiPartDatas, QByteArray &respData, QString &errMsg, int nTimeoutmsec)
{
QString strUrl = data.strUrl;
if (!data.strServer.isEmpty())
strUrl = data.strServer + ":" + QString::number(data.nPort) + "/" + data.strUrl;
const QUrl url = QUrl::fromUserInput(strUrl);
// 創(chuàng)建網(wǎng)絡(luò)請(qǐng)求
QNetworkRequest request;
request.setUrl(url);
QHttpMultiPart httpMultiPart(QHttpMultiPart::FormDataType);
// 解決Qt自動(dòng)解析MultiPart得到boundary=帶雙引號(hào)問題
for (auto iter = data.mapHeaders.begin(); iter != data.mapHeaders.end(); iter++)
{
request.setHeader(iter->first, iter->second);
}
request.setHeader(QNetworkRequest::ContentTypeHeader, "multipart/form-data;boundary=" + httpMultiPart.boundary());
FOR_EACH(itemPart, multiPartDatas)
{
QHttpPart httpPart;
{
QString strContentDisposition = QString("form-data; name=\"%1\"%2").arg(itemPart.m_sName)
.arg(itemPart.m_sExContentDisposition.isEmpty() ? "" : "; " + itemPart.m_sExContentDisposition);
httpPart.setHeader(QNetworkRequest::ContentDispositionHeader, strContentDisposition.toUtf8());
if (itemPart.m_sContentType.isEmpty() == false)
{
httpPart.setHeader(QNetworkRequest::ContentTypeHeader, itemPart.m_sContentType.toUtf8());
}
if (itemPart.m_pData)
{
httpPart.setBody(QByteArray((const char*)itemPart.m_pData, itemPart.m_nDataLen));
}
else
{
httpPart.setBody(itemPart.m_sValue.toUtf8());
}
}
httpMultiPart.append(httpPart);
}
QNetworkAccessManager qNetAccessManager;
QNetworkReply* reply = qNetAccessManager.post(request, &httpMultiPart);
if (reply == nullptr)
{
errMsg = QObject::tr("發(fā)送失敗");
return false;
}
QList<QByteArray> headers = reply->rawHeaderList();
// Set time out
QTimer timer;
timer.setInterval(nTimeoutmsec); // 設(shè)置超時(shí)時(shí)間 30 秒
timer.setSingleShot(true); // 單次觸發(fā)
// Set Loop Event
QEventLoop eventLoop;
QObject::connect(&timer, &QTimer::timeout, &eventLoop, &QEventLoop::quit);
QObject::connect(reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
timer.start();
eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
bool bResult = false;
if (timer.isActive())
{
timer.stop();
QNetworkReply::NetworkError replyError = reply->error();
if (replyError != QNetworkReply::NoError)
{
errMsg = reply->errorString();
qDebug() << "Error String : " << reply->errorString() << "\n";
}
else
{
QVariant variant = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
int nStatusCode = variant.toInt();
if (nStatusCode == 200)
{
// Accept Response
respData = reply->readAll();
bResult = true;
}
}
}
else
{
QObject::disconnect(reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
reply->abort();
qDebug() << data.strUrl << ":Timeout\n";
}
reply->deleteLater();
reply = nullptr;
return bResult;
}
bool UploadMultipartData(const QString &strURL, const CMultiPartDatas &multiPartDatas, QByteArray &respData, QString &errMsg, int nTimeoutmsec)
{
// 創(chuàng)建網(wǎng)絡(luò)請(qǐng)求
QNetworkRequest request;
request.setUrl(QUrl::fromUserInput(strURL));
QHttpMultiPart httpMultiPart(QHttpMultiPart::FormDataType);
// 解決Qt自動(dòng)解析MultiPart得到boundary=帶雙引號(hào)問題
request.setHeader(QNetworkRequest::ContentTypeHeader, "multipart/form-data;boundary=" + httpMultiPart.boundary());
foreach (itemPart, multiPartDatas)
{
QHttpPart httpPart;
{
QString strContentDisposition = QString("form-data; name=\"%1\"%2").arg(itemPart.m_sName)
.arg(itemPart.m_sExContentDisposition.isEmpty() ? "" : "; " + itemPart.m_sExContentDisposition);
httpPart.setHeader(QNetworkRequest::ContentDispositionHeader, strContentDisposition.toUtf8());
if (itemPart.m_sContentType.isEmpty() == false)
{
httpPart.setHeader(QNetworkRequest::ContentTypeHeader, itemPart.m_sContentType.toUtf8());
}
if (itemPart.m_pData)
{
httpPart.setBody(QByteArray((const char*)itemPart.m_pData, itemPart.m_nDataLen));
}
else
{
httpPart.setBody(itemPart.m_sValue.toUtf8());
}
}
httpMultiPart.append(httpPart);
}
QNetworkAccessManager qNetAccessManager;
QNetworkReply* reply = qNetAccessManager.post(request, &httpMultiPart);
if (reply == nullptr)
{
errMsg = QObject::tr("發(fā)送失敗");
return false;
}
QList<QByteArray> headers = reply->rawHeaderList();
// Set time out
QTimer timer;
timer.setInterval(nTimeoutmsec); // 設(shè)置超時(shí)時(shí)間 30 秒
timer.setSingleShot(true); // 單次觸發(fā)
// Set Loop Event
QEventLoop eventLoop;
QObject::connect(&timer, &QTimer::timeout, &eventLoop, &QEventLoop::quit);
QObject::connect(reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
timer.start();
eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
bool bResult = false;
if (timer.isActive())
{
timer.stop();
QNetworkReply::NetworkError replyError = reply->error();
if (replyError != QNetworkReply::NoError)
{
errMsg = reply->errorString();
qDebug() << "Error String : " << reply->errorString() << "\n";
}
else
{
QVariant variant = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
int nStatusCode = variant.toInt();
if (nStatusCode == 200)
{
// Accept Response
respData = reply->readAll();
bResult = true;
}
}
}
else
{
QObject::disconnect(reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
reply->abort();
qDebug() << strURL << ":Timeout\n";
}
reply->deleteLater();
reply = nullptr;
return bResult;
}
}
到此這篇關(guān)于Qt利用QNetwork實(shí)現(xiàn)上傳數(shù)據(jù)的示例代碼的文章就介紹到這了,更多相關(guān)Qt QNetwork上傳數(shù)據(jù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++?OpenCV實(shí)戰(zhàn)之零部件的自動(dòng)光學(xué)檢測(cè)
這篇文章主要為大家介紹一個(gè)C++?OpenCV的實(shí)戰(zhàn)——零部件的自動(dòng)光學(xué)檢測(cè),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2022-09-09
基于C語言實(shí)現(xiàn)創(chuàng)意多彩貪吃蛇游戲
這篇文章主要介紹了如何利用C語言實(shí)現(xiàn)一個(gè)創(chuàng)意多彩貪吃蛇游戲,這是一個(gè)純C語言外加easyx庫(kù)的繪圖函數(shù)制作而成的有趣小游戲,無需引入額外資源,感興趣的可以動(dòng)手嘗試一下2022-08-08
C語言數(shù)據(jù)結(jié)構(gòu)之單鏈表的實(shí)現(xiàn)
鏈表是一種物理存儲(chǔ)結(jié)構(gòu)上非連續(xù)、非順序的存儲(chǔ)結(jié)構(gòu),數(shù)據(jù)元素的邏輯順序是通過鏈表中的指針鏈接次序?qū)崿F(xiàn)的。本文將用C語言實(shí)現(xiàn)單鏈表,需要的可以參考一下2022-06-06

