Qt怎么用QNetwork实现上传数据

其他教程   发布日期:2023年07月07日   浏览次数:438

这篇文章主要介绍了Qt怎么用QNetwork实现上传数据的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Qt怎么用QNetwork实现上传数据文章都会有所收获,下面我们一起来看看吧。

1、利用Qt提供的类实现向服务器发送post和get请求

  1. #include <QCoreApplication>
  2. #include <QNetworkAccessManager>
  3. #include <QNetworkRequest>
  4. #include <QNetworkReply>
  5. #include <QJsonArray>
  6. #include <QJsonDocument>
  7. #include <QJsonObject>
  8. #include <QJsonParseError>
  9. #include <QJsonValue>
  10. #include <QString>
  11. #include <QDebug>
  12. #include <QFile>
  13. #include <QDateTime>
  14. #include <QDir>
  15. #include <QThread>
  16. #pragma execution_character_set("utf-8")
  17. void sendPostRequest()
  18. {
  19. QNetworkAccessManager *m_pHttpMgr = new QNetworkAccessManager();
  20. //设置url
  21. QString url = "http://localhost:80/post";
  22. //设置头信息
  23. QNetworkRequest requestInfo;
  24. requestInfo.setUrl(QUrl(url));
  25. requestInfo.setHeader(QNetworkRequest::ContentTypeHeader,QVariant("application/json"));
  26. //requestInfo.setRawHeader("Content-Type","application/json");//服务器要求的数据头部
  27. //requestInfo.setRawHeader("Accept","text/json,*/*;q=0.5");//服务器要求的数据头部
  28. //发送数据
  29. QJsonObject regionObject;
  30. regionObject.insert("name","333");
  31. regionObject.insert("height", "2");
  32. regionObject.insert("dir", "0");
  33. QJsonArray pointAry;
  34. pointAry.append(0.8);
  35. pointAry.append(1.0);
  36. pointAry.append(0.0);
  37. pointAry.append(1.8);
  38. pointAry.append(2.0);
  39. pointAry.append(0.0);
  40. regionObject.insert("points", QJsonValue(pointAry));
  41. QJsonObject jsonObject;
  42. jsonObject.insert("Code", "asss");
  43. jsonObject.insert("parentId", 0);
  44. jsonObject.insert("depot", "past");
  45. jsonObject.insert("region", QJsonValue(regionObject));
  46. QJsonDocument jsonDoc;
  47. jsonDoc.setObject(jsonObject);
  48. QByteArray qByteHttpData = jsonDoc.toJson();
  49. QNetworkReply *reply = m_pHttpMgr->post(requestInfo, qByteHttpData);
  50. //添加事件循环机制,返回后再运行后面的
  51. QEventLoop eventLoop;
  52. QObject::connect(reply, SIGNAL(finished()), &eventLoop, SLOT(quit()));
  53. eventLoop.exec(); //block until finish
  54. //错误处理
  55. if (reply->error() != QNetworkReply::NoError)
  56. {
  57. qDebug()<<"request protobufHttp handle errors here";
  58. QVariant statusCodeV = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
  59. //statusCodeV是HTTP服务器的相应码,reply->error()是Qt定义的错误码,可以参考QT的文档
  60. qDebug( "request protobufHttp found error ....code: %d %d
  61. ", statusCodeV.toInt(), (int)reply->error());
  62. qDebug(qPrintable(reply->errorString()));
  63. }
  64. //请求收到的结果
  65. QByteArray responseByte = reply->readAll();
  66. QString strRes = responseByte;
  67. qDebug() << "Post:" << strRes;
  68. }
  69. void sendGetRequest()
  70. {
  71. QNetworkAccessManager *m_pHttpMgr = new QNetworkAccessManager();
  72. //设置url
  73. QString url = "http://localhost:80/Get;
  74. QNetworkRequest requestInfo;
  75. requestInfo.setUrl(QUrl(url));
  76. //添加事件循环机制,返回后再运行后面的
  77. QEventLoop eventLoop;
  78. QNetworkReply *reply = m_pHttpMgr->get(requestInfo);
  79. QObject::connect(reply, SIGNAL(finished()), &eventLoop, SLOT(quit()));
  80. eventLoop.exec(); //block until finish
  81. //错误处理
  82. if (reply->error() != QNetworkReply::NoError)
  83. {
  84. qDebug()<<"request protobufHttp handle errors here";
  85. QVariant statusCodeV = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
  86. //statusCodeV是HTTP服务器的相应码,reply->error()是Qt定义的错误码,可以参考QT的文档
  87. qDebug( "request protobufHttp found error ....code: %d %d
  88. ", statusCodeV.toInt(), (int)reply->error());
  89. qDebug(qPrintable(reply->errorString()));
  90. }
  91. //请求返回的结果
  92. QByteArray responseByte = reply->readAll();
  93. QString strRes = responseByte;
  94. qDebug() << "Get:" << strRes;
  95. QFile file(QDir::currentPath() + "/myResponde.json");
  96. if(!file.open(QIODevice::ReadWrite))
  97. {
  98. qDebug() << "File open error";
  99. }
  100. file.write(responseByte);
  101. file.close();
  102. }
  103. int main(int argc, char *argv[])
  104. {
  105. QCoreApplication a(argc, argv);
  106. sendPostRequest();
  107. //sendGetRequest();
  108. return a.exec();
  109. }

2、实现文件上传

  1. QT += core gui
  2. QT += network
  3. greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
  4. CONFIG += c++11

Qnetworkutils.h 头文件

  1. #ifndef QNETWORKUTILS_H
  2. #define QNETWORKUTILS_H
  3. #include <iostream>
  4. #include <QString>
  5. #include <QNetworkRequest>
  6. using namespace std;
  7. namespace QNetWorkUtils
  8. {
  9. // http请求数据
  10. struct HttpRequestData
  11. {
  12. HttpRequestData()
  13. {
  14. strServer = "127.0.0.1";
  15. nPort = 8082;
  16. strUrl = "";
  17. }
  18. // 重置数据
  19. void Reset()
  20. {
  21. strServer = "127.0.0.1";
  22. nPort = 8082;
  23. strUrl = "";
  24. bytePostData.clear();
  25. mapHeaders.clear();
  26. }
  27. QString strServer;
  28. int nPort;
  29. QString strUrl;
  30. QByteArray bytePostData;
  31. std::map<QNetworkRequest::KnownHeaders, QVariant> mapHeaders;
  32. };
  33. class CMultiPartItem
  34. {
  35. public:
  36. CMultiPartItem();
  37. // 该part为一个字符串,可以指定ContentType和ExContentDisposition
  38. CMultiPartItem(const QString& strName, const QString& strValue,
  39. const QString& strContentType = "",
  40. const QString& strExContentDisposition = "");
  41. // 该part为一个二进制块,可以指定ContentType(如“image/png”,可省略)和ExContentDisposition(如“filename="123.png"”,必须)
  42. CMultiPartItem(const QString& strName, void* pData, int nLen,
  43. const QString& strContentType = "",
  44. const QString& strExContentDisposition = "");
  45. QString m_sName;
  46. QString m_sValue;
  47. void* m_pData;
  48. int m_nDataLen;
  49. QString m_sContentType;
  50. QString m_sExContentDisposition;
  51. };
  52. typedef std::vector<CMultiPartItem> CMultiPartDatas;
  53. //************************************
  54. // 方法: 发送Get请求
  55. // 返回值: bool
  56. // 参数: const HttpRequestData & data 请求数据
  57. // 参数: QByteArray & respData 返回响应数据
  58. // 参数: int nTimeoutmsec 请求超时毫秒
  59. //************************************
  60. bool HttpGet(
  61. const HttpRequestData& data,
  62. QByteArray& respData,
  63. int nTimeoutmsec = 30000,
  64. QString errMsg = QString(),
  65. int* pStatuCode = nullptr);
  66. //************************************
  67. // 方法: 发送Post请求
  68. // 返回值: bool
  69. // 参数: const HttpRequestData & data 请求数据
  70. // 参数: QByteArray & respData 返回响应数据
  71. // 参数: int nTimeoutmsec 请求超时毫秒
  72. //************************************
  73. bool HttpPost(const HttpRequestData& data,
  74. QByteArray& respData,
  75. QString& errMsg,
  76. int nTimeoutmsec = 30000);
  77. //************************************
  78. // 方法: Multipart 数据post上传
  79. // 返回值: bool
  80. // 参数: const QString& strURL 请求URL
  81. // 参数: const CMultiPartDatas& multiPartDatas 多部数据集合
  82. // 参数: QByteArray & respData 返回响应数据
  83. // 参数: int nTimeoutmsec
  84. bool UploadMultipartData(
  85. const QString& strURL,
  86. const CMultiPartDatas& multiPartDatas,
  87. QByteArray& respData,
  88. QString& errMsg,
  89. int nTimeoutmsec = 30000);
  90. bool UploadMultipartData(
  91. const HttpRequestData& data,
  92. const CMultiPartDatas& multiPartDatas,
  93. QByteArray& respData,
  94. QString& errMsg,
  95. int nTimeoutmsec = 30000);
  96. }
  97. #endif // QNETWORKUTILS_H

Qnetworkutils.cpp 源文件

  1. #include "networkutils.h"
  2. #include <QNetworkRequest>
  3. #include <QNetworkAccessManager>
  4. #include <QNetworkReply>
  5. #include <QHttpMultiPart>
  6. #include <QEventLoop>
  7. #include <QTimer>
  8. namespace QNetWorkUtils
  9. {
  10. CMultiPartItem::CMultiPartItem() :
  11. m_pData(nullptr),
  12. m_nDataLen(0)
  13. {
  14. }
  15. CMultiPartItem::CMultiPartItem(const QString& strName, const QString& strValue,
  16. const QString& strContentType /*= ""*/, const QString& strExContentDisposition /*= ""*/)
  17. {
  18. m_pData = nullptr;
  19. m_nDataLen = 0;
  20. m_sName = strName;
  21. m_sValue = strValue;
  22. m_sContentType = strContentType;
  23. m_sExContentDisposition = strExContentDisposition;
  24. }
  25. CMultiPartItem::CMultiPartItem(const QString& strName, void* pData, int nLen,
  26. const QString& strContentType /*= ""*/, const QString& strExContentDisposition /*= ""*/)
  27. {
  28. m_pData = pData;
  29. m_nDataLen = nLen;
  30. m_sName = strName;
  31. m_sContentType = strContentType;
  32. m_sExContentDisposition = strExContentDisposition;
  33. }
  34. //
  35. bool HttpGet(
  36. const HttpRequestData& data,
  37. QByteArray& respData,
  38. int nTimeoutmsec /*= 30000*/,
  39. QString& errMsg,
  40. int* pStatuCode /*= nullptr*/)
  41. {
  42. // Assemble Url
  43. QString strUrl = data.strUrl;
  44. if (!data.strServer.isEmpty())
  45. strUrl = data.strServer + ":" + QString::number(data.nPort) + "/" + data.strUrl;
  46. const QUrl url = QUrl::fromUserInput(strUrl);
  47. // Send Get Requeset
  48. QNetworkRequest request(url);
  49. for (auto iter = data.mapHeaders.begin(); iter != data.mapHeaders.end(); iter++)
  50. {
  51. request.setHeader(iter->first, iter->second);
  52. }
  53. QNetworkAccessManager qNetAccessManager;
  54. QNetworkReply* reply = qNetAccessManager.get(request);
  55. if (reply == nullptr)
  56. return false;
  57. // Set time out
  58. QTimer timer;
  59. timer.setInterval(nTimeoutmsec); // 设置超时时间 30 秒
  60. timer.setSingleShot(true); // 单次触发
  61. // Set Loop Event
  62. QEventLoop eventLoop;
  63. QObject::connect(&timer, &QTimer::timeout, &eventLoop, &QEventLoop::quit);
  64. QObject::connect(reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
  65. timer.start();
  66. int eRes = eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
  67. bool bResult = false;
  68. if (timer.isActive())
  69. {
  70. timer.stop();
  71. QNetworkReply::NetworkError replyError = reply->error();
  72. QVariant variant = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
  73. int nStatusCode = variant.toInt();
  74. if (nullptr != pStatuCode)
  75. {
  76. *pStatuCode = nStatusCode;
  77. }
  78. if (replyError != QNetworkReply::NoError)
  79. {
  80. errMsg = reply->errorString();
  81. qDebug() << "Error String : " << errMsg << "
  82. ";
  83. }
  84. else
  85. {
  86. if (nStatusCode == 200)
  87. {
  88. // Accept Response
  89. respData = reply->readAll();
  90. bResult = true;
  91. }
  92. else
  93. {
  94. bResult = false;
  95. }
  96. }
  97. }
  98. else
  99. {
  100. QObject::disconnect(reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
  101. reply->abort();
  102. qDebug() << strUrl << ":Timeout
  103. ";
  104. }
  105. reply->deleteLater();
  106. reply = nullptr;
  107. return bResult;
  108. }
  109. bool HttpPost(const HttpRequestData &data, QByteArray &respData, QString &errMsg, int nTimeoutmsec)
  110. {
  111. // Assemble Url
  112. QString strUrl = data.strUrl;
  113. if (!data.strServer.isEmpty())
  114. strUrl = data.strServer + ":" + QString::number(data.nPort) + "/" + data.strUrl;
  115. const QUrl url = QUrl::fromUserInput(strUrl);
  116. // Send Post Requeset
  117. QNetworkRequest request(url);
  118. for (auto iter = data.mapHeaders.begin(); iter != data.mapHeaders.end(); iter++)
  119. {
  120. request.setHeader(iter->first, iter->second);
  121. }
  122. QNetworkAccessManager qNetAccessManager;
  123. QNetworkReply* reply = qNetAccessManager.post(request, data.bytePostData);
  124. if (reply == nullptr)
  125. return false;
  126. // Set time out
  127. QTimer timer;
  128. timer.setInterval(nTimeoutmsec); // 设置超时时间 30 秒
  129. timer.setSingleShot(true); // 单次触发
  130. // Set Loop Event
  131. QEventLoop eventLoop;
  132. QObject::connect(&timer, &QTimer::timeout, &eventLoop, &QEventLoop::quit);
  133. QObject::connect(reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
  134. timer.start();
  135. eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
  136. bool bResult = false;
  137. if (timer.isActive())
  138. {
  139. timer.stop();
  140. QNetworkReply::NetworkError replyError = reply->error();
  141. if (replyError != QNetworkReply::NoError)
  142. {
  143. errMsg = reply->errorString();
  144. qDebug() << "Error String : " << reply->errorString() << "
  145. ";
  146. }
  147. else
  148. {
  149. QVariant variant = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
  150. int nStatusCode = variant.toInt();
  151. if (nStatusCode == 200)
  152. {
  153. // Accept Response
  154. respData = reply->readAll();
  155. bResult = true;
  156. }
  157. }
  158. }
  159. else
  160. {
  161. QObject::disconnect(reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
  162. reply->abort();
  163. errMsg = (strUrl + ":Timeout
  164. ");
  165. qDebug() << strUrl << ":Timeout
  166. ";
  167. }
  168. reply->deleteLater();
  169. reply = nullptr;
  170. return bResult;
  171. }
  172. bool UploadMultipartData(const HttpRequestData &data, const CMultiPartDatas &multiPartDatas, QByteArray &respData, QString &errMsg, int nTimeoutmsec)
  173. {
  174. QString strUrl = data.strUrl;
  175. if (!data.strServer.isEmpty())
  176. strUrl = data.strServer + ":" + QString::number(data.nPort) + "/" + data.strUrl;
  177. const QUrl url = QUrl::fromUserInput(strUrl);
  178. // 创建网络请求
  179. QNetworkRequest request;
  180. request.setUrl(url);
  181. QHttpMultiPart httpMultiPart(QHttpMultiPart::FormDataType);
  182. // 解决Qt自动解析MultiPart得到boundary=带双引号问题
  183. for (auto iter = data.mapHeaders.begin(); iter != data.mapHeaders.end(); iter++)
  184. {
  185. request.setHeader(iter->first, iter->second);
  186. }
  187. request.setHeader(QNetworkRequest::ContentTypeHeader, "multipart/form-data;boundary=" + httpMultiPart.boundary());
  188. FOR_EACH(itemPart, multiPartDatas)
  189. {
  190. QHttpPart httpPart;
  191. {
  192. QString strContentDisposition = QString("form-data; name="%1"%2").arg(itemPart.m_sName)
  193. .arg(itemPart.m_sExContentDisposition.isEmpty() ? "" : "; " + itemPart.m_sExContentDisposition);
  194. httpPart.setHeader(QNetworkRequest::ContentDispositionHeader, strContentDisposition.toUtf8());
  195. if (itemPart.m_sContentType.isEmpty() == false)
  196. {
  197. httpPart.setHeader(QNetworkRequest::ContentTypeHeader, itemPart.m_sContentType.toUtf8());
  198. }
  199. if (itemPart.m_pData)
  200. {
  201. httpPart.setBody(QByteArray((const char*)itemPart.m_pData, itemPart.m_nDataLen));
  202. }
  203. else
  204. {
  205. httpPart.setBody(itemPart.m_sValue.toUtf8());
  206. }
  207. }
  208. httpMultiPart.append(httpPart);
  209. }
  210. QNetworkAccessManager qNetAccessManager;
  211. QNetworkReply* reply = qNetAccessManager.post(request, &httpMultiPart);
  212. if (reply == nullptr)
  213. {
  214. errMsg = QObject::tr("发送失败");
  215. return false;
  216. }
  217. QList<QByteArray> headers = reply->rawHeaderList();
  218. // Set time out
  219. QTimer timer;
  220. timer.setInterval(nTimeoutmsec); // 设置超时时间 30 秒
  221. timer.setSingleShot(true); // 单次触发
  222. // Set Loop Event
  223. QEventLoop eventLoop;
  224. QObject::connect(&timer, &QTimer::timeout, &eventLoop, &QEventLoop::quit);
  225. QObject::connect(reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
  226. timer.start();
  227. eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
  228. bool bResult = false;
  229. if (timer.isActive())
  230. {
  231. timer.stop();
  232. QNetworkReply::NetworkError replyError = reply->error();
  233. if (replyError != QNetworkReply::NoError)
  234. {
  235. errMsg = reply->errorString();
  236. qDebug() << "Error String : " << reply->errorString() << "
  237. ";
  238. }
  239. else
  240. {
  241. QVariant variant = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
  242. int nStatusCode = variant.toInt();
  243. if (nStatusCode == 200)
  244. {
  245. // Accept Response
  246. respData = reply->readAll();
  247. bResult = true;
  248. }
  249. }
  250. }
  251. else
  252. {
  253. QObject::disconnect(reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
  254. reply->abort();
  255. qDebug() << data.strUrl << ":Timeout
  256. ";
  257. }
  258. reply->deleteLater();
  259. reply = nullptr;
  260. return bResult;
  261. }
  262. bool UploadMultipartData(const QString &strURL, const CMultiPartDatas &multiPartDatas, QByteArray &respData, QString &errMsg, int nTimeoutmsec)
  263. {
  264. // 创建网络请求
  265. QNetworkRequest request;
  266. request.setUrl(QUrl::fromUserInput(strURL));
  267. QHttpMultiPart httpMultiPart(QHttpMultiPart::FormDataType);
  268. // 解决Qt自动解析MultiPart得到boundary=带双引号问题
  269. request.setHeader(QNetworkRequest::ContentTypeHeader, "multipart/form-data;boundary=" + httpMultiPart.boundary());
  270. foreach (itemPart, multiPartDatas)
  271. {
  272. QHttpPart httpPart;
  273. {
  274. QString strContentDisposition = QString("form-data; name="%1"%2").arg(itemPart.m_sName)
  275. .arg(itemPart.m_sExContentDisposition.isEmpty() ? "" : "; " + itemPart.m_sExContentDisposition);
  276. httpPart.setHeader(QNetworkRequest::ContentDispositionHeader, strContentDisposition.toUtf8());
  277. if (itemPart.m_

以上就是Qt怎么用QNetwork实现上传数据的详细内容,更多关于Qt怎么用QNetwork实现上传数据的资料请关注九品源码其它相关文章!