3 Attachment(s)
Problem in using QHttp with QTimer
Given file names and time out periods, I've to download them. If the time period expires for a file, the download is canceled.
Initially, for debugging purpose, I display a message box informing that the download is successfully finished. This works for download of a single file in the main application. But problem arises when I try to download more than one file. The program just hangs!
Another problem occurs when I comment out that message box display. This time, in case of a single file, the download is finished completely. But the process doesn't exit. The task manager shows that process even after download is complete. As for multiple file download, the problem, the problem is same - the program hangs.
I have been trying to figure out the problem.
Please help me. Here's the code:
CTimedHttp header file:
Code:
#ifndef TIMEDHTTP_H
#define TIMEDHTTP_H
#include <QHttp>
class CTimedHttp
: public QHttp{
Q_OBJECT
private:
// Default time out period.
static const long INFINITE_TIME = 1000000; // 1000 seconds
// Required to initialize HTTP get ID with an improbable integer
static const long INVALID_GET_ID = -10;
// Indicates whether the request times out or not.
bool m_bIsTimedOut;
// Indicates whether the request finished without any interruption or not
bool m_bIsRequestFinished;
// Unique ID returned by HTTP get() request
long m_lHttpGetId;
// File to be downloaded
private:
void initialize();
private slots:
void requestTimeout();
void timedHttpRequestFinished(int requestId, bool error);
public:
CTimedHttp
(const QString
& hostName, quint16 port
= 80,
QObject* parent
= 0);
CTimedHttp
(const QString
& hostName,
QHttp::ConnectionMode mode, quint16 port
= 80,
QObject *parent
= 0);
void setTimedOut(bool bIsTimedOut);
bool isTimedOut();
void setRequestFinished(bool bIsRequestFinished);
bool isRequestFinished();
long getHttpGetId();
void setHttpGetId(long lHttpGetId);
void get(const QString& strPath, long lTimeoutPeriod = INFINITE_TIME);
};
#endif
CTimedHttp cpp file:
[ That message box statement is in timedHttpRequestFinished() function ]
Code:
#include <QtNetwork>
#include <QMessageBox>
#include "CTimedHttp.h"
CTimedHttp
::CTimedHttp(QObject* parent
/* = 0 */) : QHttp(parent
){
initialize();
}
CTimedHttp
::CTimedHttp(const QString
& hostName, quint16 port
/* = 80 */,
QObject* parent
/* = 0 */) : QHttp(hostName, port, parent
){
initialize();
}
CTimedHttp
::CTimedHttp(const QString
& hostName, ConnectionMode mode, quint16 port
/* = 80 */,
QObject *parent
/* = 0 */) : QHttp(hostName, mode, port, parent
) {
initialize();
}
void CTimedHttp::initialize()
{
setTimedOut(false);
setRequestFinished(false);
setHttpGetId(INVALID_GET_ID);
m_pFile = 0;
connect(this, SIGNAL(requestFinished(int, bool)), this, SLOT(timedHttpRequestFinished(int, bool)));
}
void CTimedHttp::setTimedOut(bool bIsTimedOut)
{
m_bIsTimedOut = bIsTimedOut;
}
bool CTimedHttp::isTimedOut()
{
return m_bIsTimedOut;
}
void CTimedHttp::setRequestFinished(bool bIsRequestFinished)
{
m_bIsRequestFinished = bIsRequestFinished;
}
bool CTimedHttp::isRequestFinished()
{
return m_bIsRequestFinished;
}
void CTimedHttp::setHttpGetId(long lHttpGetId)
{
m_lHttpGetId = lHttpGetId;
}
long CTimedHttp::getHttpGetId()
{
return m_lHttpGetId;
}
void CTimedHttp::get(const QString& strPath, long lTimeoutPeriod)
{
QString fileName
= fileInfo.
fileName();
if (fileName.isEmpty() == true)
{
// [TODO] : warn the user
return;
}
m_pFile
= new QFile(fileName
);
if (m_pFile
->open
(QIODevice::WriteOnly) == false) {
// [TODO] : warn the user
delete m_pFile;
m_pFile = 0;
return;
}
/* setHost(url.host()); // default to port 80
m_lHttpGetId = QHttp::get(url.path(), m_pFile);
QTimer::singleShot(lTimeoutPeriod, this, SLOT(requestTimeout()));
*/
setHost(url.host()); // default to port 80
connect(timer, SIGNAL(timeout()), this, SLOT(requestTimeout()));
timer->setSingleShot(true);
timer->start(lTimeoutPeriod);
m_lHttpGetId
= QHttp::get(url.
path(), m_pFile
);
}
void CTimedHttp::requestTimeout()
{
if (isRequestFinished() == true)
{
return;
}
setTimedOut(true);
abort();
m_pFile->close();
m_pFile->remove();
delete m_pFile;
m_pFile = 0;
// DEBUG
}
void CTimedHttp::timedHttpRequestFinished(int iRequestId, bool bError)
{
if (isTimedOut() == true
|| iRequestId != getHttpGetId()) // not the intended request
{
return;
}
timer->stop();
setRequestFinished(true);
if (bError == true)
{
m_pFile->remove();
// [TODO] : What in case of error?
return;
}
// DEBUG]
// If I comment out this statement, the process does not exit
m_pFile->close();
delete m_pFile;
m_pFile = 0;
}
Main file:
Code:
#include <QApplication>
#include "CTimedHttp.h"
int main(int argc, char *argv[])
{
CTimedHttp* timedHttp = new CTimedHttp();
timedHttp->get("http://www.google.com.bd/index.html", 60000);
timedHttp->get("http://ferdous.newsit.es/routine.html", 60000);
return app.exec();
}
Re: Problem in using QHttp with QTimer
Quote:
Originally Posted by
Ferdous
This works for download of a single file in the main application. But problem arises when I try to download more than one file. The program just hangs!
Your implementation is not suited for multiple downloads. You have just a single set of variables that control the download state, so you can't share them between multiple downloads. For example, when you invoke get() for the second time, you overwrite the m_pFile.
QHttp::get() returns an id and both requestStarted() and requestFinished() signals also carry it. You can use it to distinguish between multiple downloads.
Note also that QHttp will start its work after you start the event loop. That is when the program flow reaches "return app.exec()" line.
Quote:
Originally Posted by
Ferdous
Another problem occurs when I comment out that message box display. This time, in case of a single file, the download is finished completely. But the process doesn't exit.
As long as the event loop is running, your application will run. By default Qt stops the event loop when you close the last window. If there are no windows, you can't close the last one, so your application keeps running. You will have to stop the event loop yourself.
Re: Problem in using QHttp with QTimer
Thanks for your help.
I've added a signal
Code:
void quitApplication()
which is connected to quit() slot
Code:
connect(this, SIGNAL(quitApplication()), qApp, SLOT(quit()));
and is emitted at the end of requestTimeout() and timedHttpRequestFinished() function. Now download for a single file works fine.