来自 Qt5 中 http 客户端的 Post 方法

Posted

技术标签:

【中文标题】来自 Qt5 中 http 客户端的 Post 方法【英文标题】:Post Method from http Client in Qt5 【发布时间】:2013-10-08 23:54:02 【问题描述】:

我有一个小问题,我将在 qt 5.1.0 中为连接 http 服务器制作一个客户端程序,我通过 post 方法在 json 文件中发送请愿书,它们工作的主要方法的代码如下:

void HttpClient::sendJsonDocument(const QString typeId,const QString idClient)

QNetworkAccessManager *clientHttp=new QNetworkAccessManager();
clientHttp->clearAccessCache();
QUrl url("192.160.5.1:8383); //server adress
JsonManagment json;

QByteArray data;
data.clear();
data=("\r\n");
data.append(json.BuildJsonQuery(typeId,idClient));
data.append("\r\n");

QByteArray postDataSize = QByteArray::number(data.size());

QNetworkRequest request;
request.setUrl(url);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
request.setRawHeader("Content-Length",postDataSize);

SetHeaders(request, data);
QList <QByteArray> headers=request.rawHeaderList();
QList<QByteArray>::iterator i; 

QObject::connect(clientHttp,SIGNAL(finished(QNetworkReply *)), this, SLOT(replyFinish(QNetworkReply *)));
QNetworkReply *serverReplaying=clientHttp->post(request,data);  
QEventLoop eloop;
QObject::connect(serverReplaying,SIGNAL(finished()),  &eloop,  SLOT(quit()),Qt::UniqueConnection); 
eloop.exec( QEventLoop::ExcludeUserInputEvents );

好吧,问题是当我的程序执行一个帖子时,显然该帖子没有正确执行,因为与称为海报的 Firefox 的补充相比,数据包的内容(以及它们的数量是不同的),并且偶尔服务器正确响应,我的程序无法读取回复并重新发送帖子请求甚至 3 次,并且只收到错误关闭连接。接下来是我的槽replyFinished的代码:

void HttpClient::replyFinish(QNetworkReply *serverReplayingy)

 qDebug()<<"one step more";
 if(serverReplayingy->error() != QNetworkReply::NoError)
 
   qDebug()<<"error:"<<serverReplayingy->errorString();
   QByteArray responseData = serverReplayingy->readAll();
 

 else
  
   JsonManagment jsonFile;
   QByteArray responseData = serverReplayingy->readAll();
   jsonFile.CreateJsonFile(responseData);
   QString qstr(responseData);
   qDebug()<<qstr;
 
 return;
 

我相信服务器是正确的(因为他可以回复补充海报),我会说两个细节,第一个当我尝试检查事件循环是否正在运行时,总是给出 false,第二个,唯一的方法当我剪切 jsonfile 时,我只能得到 1 次传输和接收(1 次请愿),但我立即从服务器收到错误。

【问题讨论】:

【参考方案1】:

注意对象的生命周期(即它们是否被销毁或存活)。如果QNetworkAccessManager 和/或HttpClient 在网络请求期间被破坏,服务器响应将消失。

在您的情况下,QNetworkAccessManager 是在将请求发送到服务器的方法中创建的。因此,如果HttpClient::sendJsonDocument(); 方法在网络请求之前结束(这很可能会发生),QNetworkAccessManager 将在收到服务器响应之前被销毁,响应将消失并且您的HttpClient 将不会收到它。防止它发生的最好方法是将QNetworkAccessManager 放在一个全局变量中(或类似的东西)。

此外,请注意如何使用您的HTTPClient。如果您在类似的方法或函数中使用它:

void theFunction( /* the arguments*/ )

    // ...
    HttpClient client;
    // ...
    client.sendJsonDocument(typeID, clientID);
    // ...

HttpClient 将在函数结束时被销毁。就像上面的QNetworkAccessManager。因此,如果网络请求在HttpClient 销毁之前没有完成(这也可能发生),HttpClient 将被销毁并且无法接收响应。您必须找到一种方法来保持HttpClient 活动,直到请求完成并处理其响应(在其HttpClient::replyFinish(QNetworkReply *) 插槽中)。如果在整个请求结束前可能被销毁的对象中使用它,请小心。 一切都必须保持活力,否则您的请求将消失。

【讨论】:

谢谢,我会按照你的建议进行设计,但是服务器终于修改了,系统开始正常工作了

以上是关于来自 Qt5 中 http 客户端的 Post 方法的主要内容,如果未能解决你的问题,请参考以下文章

来自 Java 客户端的 SSL 错误,但在 Firefox 中以 POSTER 形式工作

不是来自 Google API Oauth 的客户端的有效来源

Python:如何将 HTTP POST 转换为 JSON 格式

Golang net/http客户端的使用

实战Node.js之GET/POST请求在Web 应用架构在客户端的使用

如何用get方post方式向http接口发送数据