伙伴云客服论坛»论坛 S区 S软件开发 查看内容

0 评论

0 收藏

分享

Qt利用QNetwork实现上传数据的示例代码

目录

    1、利用Qt提供的类实现向效劳器发送post和get恳求2、实现文件上传


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\n", statusCodeV.toInt(), (int)reply->error());
  61.         qDebug(qPrintable(reply->errorString()));
  62.     }
  63.     //恳求收到的结果
  64.     QByteArray responseByte = reply->readAll();
  65.     QString strRes = responseByte;
  66.     qDebug() << "Post:" << strRes;
  67. }
  68. void sendGetRequest()
  69. {
  70.     QNetworkAccessManager *m_pHttpMgr = new QNetworkAccessManager();
  71.     //设置url
  72.     QString url = "http://localhost:80/Get;
  73.     QNetworkRequest requestInfo;
  74.     requestInfo.setUrl(QUrl(url));
  75.     //添加事件循环机制,返回后再运行后面的
  76.     QEventLoop eventLoop;
  77.     QNetworkReply *reply =  m_pHttpMgr->get(requestInfo);
  78.     QObject::connect(reply, SIGNAL(finished()), &eventLoop, SLOT(quit()));
  79.     eventLoop.exec();       //block until finish
  80.     //错误处置
  81.     if (reply->error() != QNetworkReply::NoError)
  82.     {
  83.         qDebug()<<"request protobufHttp handle errors here";
  84.         QVariant statusCodeV = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
  85.         //statusCodeV是HTTP效劳器的相应码,reply->error()是Qt定义的错误码,可以参考QT的文档
  86.         qDebug( "request protobufHttp found error ....code: %d %d\n", statusCodeV.toInt(), (int)reply->error());
  87.         qDebug(qPrintable(reply->errorString()));
  88.     }
  89.     //恳求返回的结果
  90.     QByteArray responseByte = reply->readAll();
  91.     QString strRes = responseByte;
  92.     qDebug() << "Get:" << strRes;
  93.     QFile file(QDir::currentPath() + "/myResponde.json");
  94.     if(!file.open(QIODevice::ReadWrite))
  95.     {
  96.         qDebug() << "File open error";
  97.     }
  98.     file.write(responseByte);
  99.     file.close();
  100. }
  101. int main(int argc, char *argv[])
  102. {
  103.     QCoreApplication a(argc, argv);
  104.     sendPostRequest();
  105.     //sendGetRequest();
  106.     return a.exec();
  107. }
复制代码
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 << "\n";
  82.             }
  83.             else
  84.             {
  85.                 if (nStatusCode == 200)
  86.                 {
  87.                     // Accept Response
  88.                     respData = reply->readAll();
  89.                     bResult = true;
  90.                 }
  91.                 else
  92.                 {
  93.                     bResult = false;
  94.                 }
  95.             }
  96.         }
  97.         else
  98.         {
  99.             QObject::disconnect(reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
  100.             reply->abort();
  101.             qDebug() << strUrl << ":Timeout\n";
  102.         }
  103.         reply->deleteLater();
  104.         reply = nullptr;
  105.         return bResult;
  106.     }
  107.     bool HttpPost(const HttpRequestData &data, QByteArray &respData, QString &errMsg, int nTimeoutmsec)
  108.     {
  109.         // Assemble Url
  110.         QString strUrl = data.strUrl;
  111.         if (!data.strServer.isEmpty())
  112.             strUrl = data.strServer + ":" + QString::number(data.nPort) + "/" + data.strUrl;
  113.         const QUrl url = QUrl::fromUserInput(strUrl);
  114.         // Send Post Requeset
  115.         QNetworkRequest request(url);
  116.         for (auto iter = data.mapHeaders.begin(); iter != data.mapHeaders.end(); iter++)
  117.         {
  118.             request.setHeader(iter->first, iter->second);
  119.         }
  120.         QNetworkAccessManager qNetAccessManager;
  121.         QNetworkReply* reply = qNetAccessManager.post(request, data.bytePostData);
  122.         if (reply == nullptr)
  123.             return false;
  124.         // Set time out
  125.         QTimer timer;
  126.         timer.setInterval(nTimeoutmsec);    // 设置超时时间 30 秒
  127.         timer.setSingleShot(true);          // 单次触发
  128.         // Set Loop Event
  129.         QEventLoop eventLoop;
  130.         QObject::connect(&timer, &QTimer::timeout, &eventLoop, &QEventLoop::quit);
  131.         QObject::connect(reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
  132.         timer.start();
  133.         eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
  134.         bool bResult = false;
  135.         if (timer.isActive())
  136.         {
  137.             timer.stop();
  138.             QNetworkReply::NetworkError replyError = reply->error();
  139.             if (replyError != QNetworkReply::NoError)
  140.             {
  141.                 errMsg = reply->errorString();
  142.                 qDebug() << "Error String : " << reply->errorString() << "\n";
  143.             }
  144.             else
  145.             {
  146.                 QVariant variant = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
  147.                 int nStatusCode = variant.toInt();
  148.                 if (nStatusCode == 200)
  149.                 {
  150.                     // Accept Response
  151.                     respData = reply->readAll();
  152.                     bResult = true;
  153.                 }
  154.             }
  155.         }
  156.         else
  157.         {
  158.             QObject::disconnect(reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
  159.             reply->abort();
  160.             errMsg = (strUrl + ":Timeout\n");
  161.             qDebug() << strUrl << ":Timeout\n";
  162.         }
  163.         reply->deleteLater();
  164.         reply = nullptr;
  165.         return bResult;
  166.     }
  167.     bool UploadMultipartData(const HttpRequestData &data, const CMultiPartDatas &multiPartDatas, QByteArray &respData, QString &errMsg, int nTimeoutmsec)
  168.     {
  169.         QString strUrl = data.strUrl;
  170.         if (!data.strServer.isEmpty())
  171.             strUrl = data.strServer + ":" + QString::number(data.nPort) + "/" + data.strUrl;
  172.         const QUrl url = QUrl::fromUserInput(strUrl);
  173.         // 创建网络恳求
  174.         QNetworkRequest request;
  175.         request.setUrl(url);
  176.         QHttpMultiPart httpMultiPart(QHttpMultiPart::FormDataType);
  177.         // 处置Qt自动解析MultiPart得到boundary=带双引号问题
  178.         for (auto iter = data.mapHeaders.begin(); iter != data.mapHeaders.end(); iter++)
  179.         {
  180.             request.setHeader(iter->first, iter->second);
  181.         }
  182.         request.setHeader(QNetworkRequest::ContentTypeHeader, "multipart/form-data;boundary=" + httpMultiPart.boundary());
  183.         FOR_EACH(itemPart, multiPartDatas)
  184.         {
  185.             QHttpPart httpPart;
  186.             {
  187.                 QString strContentDisposition = QString("form-data; name="%1"%2").arg(itemPart.m_sName)
  188.                     .arg(itemPart.m_sExContentDisposition.isEmpty() ? "" : "; " + itemPart.m_sExContentDisposition);
  189.                 httpPart.setHeader(QNetworkRequest::ContentDispositionHeader, strContentDisposition.toUtf8());
  190.                 if (itemPart.m_sContentType.isEmpty() == false)
  191.                 {
  192.                     httpPart.setHeader(QNetworkRequest::ContentTypeHeader, itemPart.m_sContentType.toUtf8());
  193.                 }
  194.                 if (itemPart.m_pData)
  195.                 {
  196.                     httpPart.setBody(QByteArray((const char*)itemPart.m_pData, itemPart.m_nDataLen));
  197.                 }
  198.                 else
  199.                 {
  200.                     httpPart.setBody(itemPart.m_sValue.toUtf8());
  201.                 }
  202.             }
  203.             httpMultiPart.append(httpPart);
  204.         }
  205.         QNetworkAccessManager qNetAccessManager;
  206.         QNetworkReply* reply = qNetAccessManager.post(request, &httpMultiPart);
  207.         if (reply == nullptr)
  208.         {
  209.             errMsg = QObject::tr("发送失败");
  210.             return false;
  211.         }
  212.         QList<QByteArray> headers = reply->rawHeaderList();
  213.         // Set time out
  214.         QTimer timer;
  215.         timer.setInterval(nTimeoutmsec);    // 设置超时时间 30 秒
  216.         timer.setSingleShot(true);          // 单次触发
  217.         // Set Loop Event
  218.         QEventLoop eventLoop;
  219.         QObject::connect(&timer, &QTimer::timeout, &eventLoop, &QEventLoop::quit);
  220.         QObject::connect(reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
  221.         timer.start();
  222.         eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
  223.         bool bResult = false;
  224.         if (timer.isActive())
  225.         {
  226.             timer.stop();
  227.             QNetworkReply::NetworkError replyError = reply->error();
  228.             if (replyError != QNetworkReply::NoError)
  229.             {
  230.                 errMsg = reply->errorString();
  231.                 qDebug() << "Error String : " << reply->errorString() << "\n";
  232.             }
  233.             else
  234.             {
  235.                 QVariant variant = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
  236.                 int nStatusCode = variant.toInt();
  237.                 if (nStatusCode == 200)
  238.                 {
  239.                     // Accept Response
  240.                     respData = reply->readAll();
  241.                     bResult = true;
  242.                 }
  243.             }
  244.         }
  245.         else
  246.         {
  247.             QObject::disconnect(reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
  248.             reply->abort();
  249.             qDebug() << data.strUrl << ":Timeout\n";
  250.         }
  251.         reply->deleteLater();
  252.         reply = nullptr;
  253.         return bResult;
  254.     }
  255.     bool UploadMultipartData(const QString &strURL, const CMultiPartDatas &multiPartDatas, QByteArray &respData, QString &errMsg, int nTimeoutmsec)
  256.     {
  257.         // 创建网络恳求
  258.         QNetworkRequest request;
  259.         request.setUrl(QUrl::fromUserInput(strURL));
  260.         QHttpMultiPart httpMultiPart(QHttpMultiPart::FormDataType);
  261.         // 处置Qt自动解析MultiPart得到boundary=带双引号问题
  262.         request.setHeader(QNetworkRequest::ContentTypeHeader, "multipart/form-data;boundary=" + httpMultiPart.boundary());
  263.         foreach (itemPart, multiPartDatas)
  264.         {
  265.             QHttpPart httpPart;
  266.             {
  267.                 QString strContentDisposition = QString("form-data; name="%1"%2").arg(itemPart.m_sName)
  268.                     .arg(itemPart.m_sExContentDisposition.isEmpty() ? "" : "; " + itemPart.m_sExContentDisposition);
  269.                 httpPart.setHeader(QNetworkRequest::ContentDispositionHeader, strContentDisposition.toUtf8());
  270.                 if (itemPart.m_sContentType.isEmpty() == false)
  271.                 {
  272.                     httpPart.setHeader(QNetworkRequest::ContentTypeHeader, itemPart.m_sContentType.toUtf8());
  273.                 }
  274.                 if (itemPart.m_pData)
  275.                 {
  276.                     httpPart.setBody(QByteArray((const char*)itemPart.m_pData, itemPart.m_nDataLen));
  277.                 }
  278.                 else
  279.                 {
  280.                     httpPart.setBody(itemPart.m_sValue.toUtf8());
  281.                 }
  282.             }
  283.             httpMultiPart.append(httpPart);
  284.         }
  285.         QNetworkAccessManager qNetAccessManager;
  286.         QNetworkReply* reply = qNetAccessManager.post(request, &httpMultiPart);
  287.         if (reply == nullptr)
  288.         {
  289.             errMsg = QObject::tr("发送失败");
  290.             return false;
  291.         }
  292.         QList<QByteArray> headers = reply->rawHeaderList();
  293.         // Set time out
  294.         QTimer timer;
  295.         timer.setInterval(nTimeoutmsec);    // 设置超时时间 30 秒
  296.         timer.setSingleShot(true);          // 单次触发
  297.         // Set Loop Event
  298.         QEventLoop eventLoop;
  299.         QObject::connect(&timer, &QTimer::timeout, &eventLoop, &QEventLoop::quit);
  300.         QObject::connect(reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
  301.         timer.start();
  302.         eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
  303.         bool bResult = false;
  304.         if (timer.isActive())
  305.         {
  306.             timer.stop();
  307.             QNetworkReply::NetworkError replyError = reply->error();
  308.             if (replyError != QNetworkReply::NoError)
  309.             {
  310.                 errMsg = reply->errorString();
  311.                 qDebug() << "Error String : " << reply->errorString() << "\n";
  312.             }
  313.             else
  314.             {
  315.                 QVariant variant = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
  316.                 int nStatusCode = variant.toInt();
  317.                 if (nStatusCode == 200)
  318.                 {
  319.                     // Accept Response
  320.                     respData = reply->readAll();
  321.                     bResult = true;
  322.                 }
  323.             }
  324.         }
  325.         else
  326.         {
  327.             QObject::disconnect(reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
  328.             reply->abort();
  329.             qDebug() << strURL << ":Timeout\n";
  330.         }
  331.         reply->deleteLater();
  332.         reply = nullptr;
  333.         return bResult;
  334.     }
  335. }
复制代码
到此这篇关于Qt利用QNetwork实现上传数据的示例代码的文章就介绍到这了,更多相关Qt QNetwork上传数据内容请搜索网站以前的文章或继续阅读下面的相关文章希望大家以后多多支持网站!

回复

举报 使用道具

相关帖子
全部回复
暂无回帖,快来参与回复吧
本版积分规则 高级模式
B Color Image Link Quote Code Smilies

萌晓许
注册会员
主题 22
回复 14
粉丝 0
|网站地图
快速回复 返回顶部 返回列表