在Qt5中从http客户端发布方法

时间:2013-10-08 23:54:03

标签: 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次,只得到错误Clossed 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;
 }

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

1 个答案:

答案 0 :(得分: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 *)槽中)。如果在可能在整个请求结束时被破坏的对象中使用它,请小心。 一切都必须保持活力,否则您的请求将会消失。