先说结论,升级QT到最新版本即可解决!确认官方bug!
折腾了四五天了,最后在Qt论坛找到了答案,确认有问题的版本为qt-opensource-windows-x86-5.14.1.exe:
确认已经修复问题的版本qt-opensource-windows-x86-5.12.10和qt-opensource-windows-x86-5.9.9.exe:
因为5.9.9和5.14.1关于的版本显示一致,所以通过安装文件的名字区分比较好!
===============分割线===================
被这个问题困扰了几天,都想换个http库了,但是为了尽量使用纯Qt代码,于是只能继续尝试,改进类。
修改思路:
1.外部传递manager,公用一个,避免反复申请,析构。
2.取消继承自QObject,避免未知问题。
3.注意断开信号与槽(因为不知道内部信号与槽源代码,怀疑这个也可能导致内存泄露)
4.该关闭的关闭,该删除的删除
#ifndef CLIENTPROGRESS_H
#define CLIENTPROGRESS_H
#include <QObject>
#include <QNetworkRequest>
#include <QNetworkReply>
class ClientProgress
{
public:
explicit ClientProgress(QNetworkAccessManager* pManager);
~ClientProgress();
public:
int CheckClientProgress(std::string strHost, std::string strProgressFilePathName, std::string& strInfo);
private:
int parseReplyData(QNetworkReply* reply, QByteArray& data);
int requestClientUrl(const QString& strHost, const QByteArray& baPostData, QByteArray& baAnswer, int nTimeoutSeconds = 10);
void setRequestHeader(QNetworkRequest &request)
{
request.setRawHeader("Content-Type", "charset='utf-8'");
request.setRawHeader("Content-Type", "application/json");
}
private:
QNetworkAccessManager* m_naManager;
signals:
};
#endif // CLIENTPROGRESS_H
实现:
#include "ClientProgress.h"
#include <QNetworkAccessManager>
#include <QEventLoop>
#include <QTimer>
#include "taskFuncList.h"
#include "JsonParser.h"
ClientProgress::ClientProgress(QNetworkAccessManager *pManager)
{
Q_ASSERT(pManager != nullptr);
m_naManager = nullptr;
if (pManager)
{
m_naManager = pManager;
}
}
ClientProgress::~ClientProgress()
{
}
int ClientProgress::CheckClientProgress(std::string strHost, std::string strProgressFilePathName, std::string &strInfo)
{
QStringList lKeys, lValues;
lKeys.push_back("ip");
lKeys.push_back("fun");
lKeys.push_back("file");
lValues.push_back(strHost.c_str());
lValues.push_back(QString::number(enProgress));
lValues.push_back(strProgressFilePathName.c_str());
QByteArray baPostData = JsonParser::StringList2ByteArray(lKeys, lValues);
QByteArray baReply;
if (requestClientUrl(strHost.c_str(), baPostData, baReply, 2) == 0)
{
QString strProgress;
if (JsonParser::ParseRootKeyValue(baReply, "progress", strProgress) == 0)
{
QStringList lProgress = strProgress.split(",");
if (lProgress.size() >= 2)
{
int nProgress = lProgress[0].toInt();
if (nProgress >= 0 && nProgress <= 100)
{
strInfo = lProgress[1].toUtf8().data();
return nProgress;
}
}
}
}
return 0;
}
int ClientProgress::parseReplyData(QNetworkReply *reply, QByteArray &data)
{
if (reply == nullptr)
{
return -1;
}
if(reply->error() != QNetworkReply::NoError)
{
return -2;
}
else
{
//输出内容
data = reply->readAll();
}
return 0;
}
int ClientProgress::requestClientUrl(const QString &strHost, const QByteArray &baPostData, QByteArray &baAnswer, int nTimeoutSeconds)
{
if (m_naManager == nullptr)
{
return -1;
}
QString strCmdUrl = QString("http://") + strHost + ":" + QString::number(9998);
QNetworkRequest request(strCmdUrl);
setRequestHeader(request);
QNetworkReply* reply = m_naManager->post(request, baPostData);
QEventLoop eventloop;
QMetaObject::Connection conRet = QObject::connect(reply, SIGNAL(finished()), &eventloop, SLOT(quit()));
Q_ASSERT(conRet);
QTimer timer;
timer.singleShot(nTimeoutSeconds * 1000, &eventloop, SLOT(quit()));
timer.start();
eventloop.exec(QEventLoop::ExcludeUserInputEvents);
if (timer.isActive())
{
QByteArray baReply;
if (parseReplyData(reply, baReply) == 0)
{
//超时,未知状态
QObject::disconnect(reply, SIGNAL(finished()), &eventloop, SLOT(quit()));
reply->abort();
reply->close();
reply->deleteLater();
baAnswer = baReply;
return 0;
}
}
//超时,未知状态
QObject::disconnect(reply, SIGNAL(finished()), &eventloop, SLOT(quit()));
reply->abort();
reply->close();
reply->deleteLater();
return -1;
}
继续长时间测试中,目前测试的结果是1、3、4无效,正在测试2,看起来初见成效,后续将记录测试结果!