QFtp & QTimer timeout on connectToHost issues (Qt 5.5.1 Win32 VS2013)
-
Hello! Got some issues using QFtp. I try to write reliable code to timeout a QFtp connectToHost and loop. The main issue here is the timeout works but the QFtp class is sort of locked and the program does not crash (instantly) but on app close the exits code is 255 instead of 0.
// FTP ftp = new QFtp(this); connect(ftp, SIGNAL(listInfo(QUrlInfo)), this, SLOT(getListInfo(QUrlInfo))); connect(ftp, SIGNAL(done(bool)), this, SLOT(isDone(bool))); // timer timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(ftpTimeout())); // loop loop = new QEventLoop(this);
The FTP:
void ftpTest::isDone(bool) { if(ftp->error()) { qDebug() << "Error: " << ftp->error(); qDebug() << "ErrorString: " << ftp->errorString(); } if(timer->isActive()) { timer->stop(); } }
For the timer:
void ftpTest::ftpTimeout() { ftp->abort(); ftp->deleteLater(); loop->exit(0); qDebug() << "ftpTimeout"; }
To get the dir listing:
loop->connect(ftp, SIGNAL(done(bool)), loop, SLOT(quit())); timer->setSingleShot(1); timer->start(5000); ftp->connectToHost(Host, Port); ftp->login(Username, Password); ftp->cd(Path); ftp->list(); ftp->close(); loop->exec();
Any ideas what i did wrong here?
Thanks! -
Hi @qDebug,
First up, if this is new code, you probably shouldn't be using QFtp...
Qt 5 / C++ API changes / Changes to Qt Network says:
The QFtp and QUrlInfo classes are no longer exported. Use QNetworkAccessManager instead. Programs that require raw FTP or HTTP streams can use the Qt FTP and Qt HTTP compatibility add-on modules that provide the QFtp and QHttp classes as they existed in Qt 4.
So I'd recommend re-factoring to use QNetworkAccessManager instead, if this is the early stages of a new project (unless you need that "raw FTP" access). Perhaps have a read of High Level Network Operations for HTTP and FTP, if you haven't already.
As for your code above, why are you creating your own QEventLoop? You shouldn't need to for most use cases. Simply rely on the application's loop instead, like:
int main(int argc, char *argv[]) { QApplication app(argc, argv); // some of your code. connect(ftp, SIGNAL(done(bool)), app, SLOT(quit())); // more of your code. return app.exec(); }
Cheers.
-
@Paul-Colby Hi!
Well, i use QFtp because i need the directory listing form the FTP server. As far as i know QNetworkAccessManager does only support put and get, but no listings, cd or any other FTP commands. And QNetworkAccessManager does not support a blind shot "ftp://user:pass@127.0.0.1:21/download all files in some dir/*".
I create my own loop because i have to. I loop through a lot of data and the only way i know to wait for the next is to connect to a loop so not 1.000.0000 connections will be created at the same time. If there is any better way, please correct me.
for(a lot of data) { loop->connect(ftp, SIGNAL(done(bool)), loop, SLOT(quit())); timer->setSingleShot(1); timer->start(5000); ftp->connectToHost(Host, Port); ftp->login(Username, Password); ftp->cd(Path); ftp->list(); ftp->close(); loop->exec(); }
-
@qDebug said:
Well, i use QFtp because i need the directory listing form the FTP server. ... And QNetworkAccessManager does not support a blind shot "ftp://user:pass@127.0.0.1:21/download all files in some dir/*".
Fair enough :)
I create my own loop because i have to. I loop through a lot of data and the only way i know to wait for the next is to connect to a loop so not 1.000.0000 connections will be created at the same time.
To avoid creating too many requests, rather than trying to use an explicit even loop, I'd:
1 connect a slot to the QFtp::commandFinished signal;
2 just loop through just the first n items (eg the first 5) of "a lot of data";
3 in the slot you connected in step #1, check if the command was QFtp::list, if so, repeat step #2 for the next one item.Does that makes sense?
Cheers.
-
The loop is not my problem, there is about 2000 lines of code behind it, the loop works. I would really appreciate if we can focus on the timeout problem. Because the timeout handling will still be broken whatever i do with loops. I did test it with or without my own loop, it does not timeout if the server is reachable but the ftp is not (in some cases). I know that because i added the loop later.
-
Hi,
Just to be sure we all use the same stuff. Where did you get QFtp from ?
-
You do realize that you have a leak there. Even if the objects will be deleted once the parent itself is deleted, you are currently filling your memory with QFtp objects.
-
My bad, from your last post, I understood that you replaced the deleteLater call by a new allocation.
Why are you calling delete right after deleteLater ?