Ferdous
5th September 2008, 10:18
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:
#ifndef TIMEDHTTP_H
#define TIMEDHTTP_H
#include <QHttp>
class QFile;
class QTimer;
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
QFile *m_pFile;
QTimer *timer;
private:
void initialize();
private slots:
void requestTimeout();
void timedHttpRequestFinished(int requestId, bool error);
public:
CTimedHttp(QObject* parent = 0);
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 ]
#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)
{
QUrl url(strPath);
QFileInfo fileInfo(url.path());
QString fileName = fileInfo.fileName();
if (fileName.isEmpty() == true)
{
// [TODO] : warn the user
QMessageBox::critical(0, "ERROR", "You haven't specified any file name!", QMessageBox::Ok);
return;
}
m_pFile = new QFile(fileName);
if (m_pFile->open(QIODevice::WriteOnly) == false)
{
// [TODO] : warn the user
QMessageBox::critical(0, "ERROR", "Cann't open the file!", QMessageBox::Ok);
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
timer = new QTimer();
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
QMessageBox::critical(0, "ERROR", "Request timed out!", QMessageBox::Ok);
}
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?
QMessageBox::critical(0, "ERROR", "The request finished with error!", QMessageBox::Ok);
return;
}
// DEBUG]
// If I comment out this statement, the process does not exit
QMessageBox::information(0, "Info", "Download is successful", QMessageBox::Ok);
m_pFile->close();
delete m_pFile;
m_pFile = 0;
}
Main file:
#include <QApplication>
#include "CTimedHttp.h"
int main(int argc, char *argv[])
{
QApplication app(argc, 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();
}
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:
#ifndef TIMEDHTTP_H
#define TIMEDHTTP_H
#include <QHttp>
class QFile;
class QTimer;
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
QFile *m_pFile;
QTimer *timer;
private:
void initialize();
private slots:
void requestTimeout();
void timedHttpRequestFinished(int requestId, bool error);
public:
CTimedHttp(QObject* parent = 0);
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 ]
#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)
{
QUrl url(strPath);
QFileInfo fileInfo(url.path());
QString fileName = fileInfo.fileName();
if (fileName.isEmpty() == true)
{
// [TODO] : warn the user
QMessageBox::critical(0, "ERROR", "You haven't specified any file name!", QMessageBox::Ok);
return;
}
m_pFile = new QFile(fileName);
if (m_pFile->open(QIODevice::WriteOnly) == false)
{
// [TODO] : warn the user
QMessageBox::critical(0, "ERROR", "Cann't open the file!", QMessageBox::Ok);
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
timer = new QTimer();
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
QMessageBox::critical(0, "ERROR", "Request timed out!", QMessageBox::Ok);
}
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?
QMessageBox::critical(0, "ERROR", "The request finished with error!", QMessageBox::Ok);
return;
}
// DEBUG]
// If I comment out this statement, the process does not exit
QMessageBox::information(0, "Info", "Download is successful", QMessageBox::Ok);
m_pFile->close();
delete m_pFile;
m_pFile = 0;
}
Main file:
#include <QApplication>
#include "CTimedHttp.h"
int main(int argc, char *argv[])
{
QApplication app(argc, 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();
}