c++ - Qt5 中 http 客户端的 Post 方法

标签 c++ http post qt5 qnetworkaccessmanager

我有一个小问题,我将在 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 );
}

好吧,问题是当我的程序执行一个帖子时,显然这个帖子没有正确执行,因为与一个名为 poster 的 firefox 补充相比,数据包的内容(以及它们的数量是不同的),偶尔服务器正确响应,我的程序无法读取回复并重新发送请愿书甚至 3 次,并且只收到错误 Closed connection。接下来是我的插槽 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,第二个,唯一的方法当我剪切 json 文件时,我只能得到 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 *) 槽中)。如果您在可能在整个请求结束之前销毁的对象中使用它,请小心。 一切都必须保持活力,否则您的请求就会消失。

关于c++ - Qt5 中 http 客户端的 Post 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19260610/

相关文章:

json - 使用 json 的 FOSRest Symfony POST

javascript - 为什么 POST 请求后会显示页面?

c++ - 将图像的像素复制到数组的最快方法是什么?

c++ - Perl CGI 与 mod_perl WebServer 中的 C CGI

c++ - 在 std::list 中,std::distance(it.begin(), std::prev(it.end())) 是否等于 list.size()?

python - 获取 HTTP 请求的 TTFB(到第一个字节的时间)

c++ - 我可以只对那些 std::is_trivially_move_* 东西使用 memcpy 吗?

linux - curl 并检查 403 错误代码

java - 为什么 HttpURLConnection 不发送 HTTP 请求

php - 在 php 中通过 post 接收 xml 文件