QNetworkAccessManager内存问题

时间:2016-05-10 07:15:52

标签: c++ qt qnetworkaccessmanager qnetworkreply

我正在开发一个应用程序,它使用QtNetworkAccessManager向服务器发送请求并存储回复。我已经使它工作但内存使用量不断增加,直到它阻止整个PC。我认为问题与调用deletelater()和事件循环有关,但我看不出如何修复它。这是代码:

的main.cpp

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    ReadConfig();
    Ethernet M2;
    return a.exec();
}

Ethernet.h

class Ethernet : public QObject
{
    Q_OBJECT

public:
    Ethernet();
    ~Ethernet();
    QTimer *timer;

private
    QNetworkAccessManager *manager;

public slots:
    void Cycle();
    void replyAuthenticationRequired(QNetworkReply *reply, QAuthenticator *auth);
    void replyFinished(QNetworkReply *reply);
};

Ethernet.cpp

Ethernet::Ethernet() 
{
    timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(Cycle()));
    timer->start(1000);

    manager = new QNetworkAccessManager(this);
    connect(manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), this, SLOT(replyAuthenticationRequired(QNetworkReply*,QAuthenticator*)));
    connect(manager, SIGNAL(finished(QNetworkReply*)), this,     SLOT(replyFinished(QNetworkReply*)));
}

void Ethernet::Cycle()
{
    for (BYTE i=0; i< NUM_TOTAL_VEHICLES; i++)
    {
        FailCheck(i,FILTER_VALUE_PRIORITY_A1);
        FailCheck(i,FILTER_VALUE_PRIORITY_A);
        FailCheck(i,FILTER_VALUE_PRIORITY_B);
        FailCheck(i,FILTER_VALUE_PRIORITY_C);
    }
}

void Ethernet::FailCheck (BYTE coach, BYTE priority)
{
    //Build a valid URL
    QString qsURL = "http://";
    ...
    ..
    .
    //

    manager->get(QNetworkRequest(QUrl(qsURL)));
}

void Ethernet::replyAuthenticationRequired(QNetworkReply *reply, QAuthenticator *auth)
{
   if(!reply->error())
   {
       auth->setUser(DB_USR);
       auth->setPassword(DB_PWD);
   }
   reply->deleteLater();
}

void Ethernet::replyFinished (QNetworkReply *reply)
{
    if(!reply->error())
    {
        //Do some task with the reply;
    }
    reply->deleteLater();
}

我将不胜感激任何建议。谢谢!

3 个答案:

答案 0 :(得分:0)

您需要从QObject继承以太网以正确使用事件循环

答案 1 :(得分:0)

您不得制作QNetworkAccessManager的多个对象。正如文档所说:“一个QNetworkAccessManager应该足以满足整个Qt应用程序的需求。” Reference link。如果您创建以太网类的多个对象,那么它将产生内存问题。而且您还需要将QObject作为以太网的基类。

manager = new QNetworkAccessManager(this);
this (Ethernet) must have QObject as base class.

答案 2 :(得分:0)

如果您的类不是线程,则它不应继承QThread。从QObject继承,或者如果不能,则从M2线程开始。现在你的Ethernet的线程循环不起作用,似乎网络回复与你的Ethernet事件循环具有亲缘关系(删除它们的请求被发布到{{} 1}}事件循环,未启动)

或者更确切地说,您的插槽根本不会执行,因此网络回复会被创建,但由于您的插槽从未执行过(因为上述原因),因此它们永远不会被删除,所以如果我没有弄错的话网络回复在主线程中生效,因此Ethernet应该正确删除它们,但永远不会被调用。