Results 1 to 12 of 12

Thread: Question about ftp using Qt

  1. #1
    Join Date
    Dec 2006
    Posts
    426
    Thanks
    8
    Thanked 18 Times in 17 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Question about ftp using Qt

    Hi,

    I need to ftp 30000 files from a particular website with same username and password, I am using the following code.

    My question: will the ftp login 30000 times, or will it keep the connection alive during the entire ftp session until all files are ftped? Also how to I set timeout?

    Thanks

    Qt Code:
    1. QUrl url;
    2. url.setUserName( "ftp" );
    3. url.setPassword( "xxx" );
    4.  
    5. QNetworkAccessManager manager;
    6.  
    7. QEventLoop eventLoop;
    8.  
    9. connect( &manager, SIGNAL( finished( QNetworkReply* ) ),
    10. &eventLoop, SLOT( quit() ) );
    11.  
    12.  
    13. foreach ( const QString& file, fileList ) {
    14.  
    15. QUrl.setUurl( "ftp://ftp.xxx.com/" + file );
    16. QNetworkReply *reply = manager.get( QNetworkRequest( url ) );
    17.  
    18. /// block until each file is finished, how do I set timeout in the next line?
    19. eventLoop.exec();
    20.  
    21. /// get the reply content
    22. reply->readAll();
    23. ....
    24.  
    25. reply->deleteLater();
    26.  
    27. }
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Question about ftp using Qt

    QNetworkAccessManager will reuse connections for HTTP but I have never investigated FTP. You can check with Wireshark fairly quickly. In your example (clearly not your real code) you are not sending credentials so there might only be an anonymous FTP login.

    If you were not explicitly serialising your requests QNetworkAccessManager will also process several at the same time. It would be a good idea to check if the transfer was successful before you rely on the data.

    Set the timeout for what?
    Last edited by ChrisW67; 17th March 2014 at 04:17.

  3. #3
    Join Date
    Dec 2006
    Posts
    426
    Thanks
    8
    Thanked 18 Times in 17 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Question about ftp using Qt

    Thanks!

    Set timeout for connection or maximum duration of the ftp job. I have managed to use QTimer for that.

    However, I now have another problem.

    I connect to QNetworkAccessManager::finished signal, and then read data using reply->readAll(). Problem is reply sometimes appends new line "\n" in between data chunk, causing the xml file to break.

    For example, tag <conversion> becomes:

    <convers
    ion>


    This cause xml parser to fail. The xml file itself has many new lines, so I don't to use QString::replace( "\n", "" ), because this will cause entire xml file to be a single line.

    How do I fix this problem?

    Thanks

  4. #4
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Question about ftp using Qt

    I connect to QNetworkAccessManager::finished signal, and then read data using reply->readAll(). Problem is reply sometimes appends new line "\n" in between data chunk, causing the xml file to break.
    No, Qt doesn't. That raises the question, what are you actually doing to the QByteArray after readAll() gives it to you?

  5. #5
    Join Date
    Dec 2006
    Posts
    426
    Thanks
    8
    Thanked 18 Times in 17 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Question about ftp using Qt

    Quote Originally Posted by ChrisW67 View Post
    No, Qt doesn't. That raises the question, what are you actually doing to the QByteArray after readAll() gives it to you?
    I did:

    QString content = reply->readAll();

    Then parse the content using xml parser, and found that "\n" is inserted in between data in some of the files.

  6. #6
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Question about ftp using Qt

    Is the FTP server public? Example file?
    Last edited by ChrisW67; 18th March 2014 at 07:30.

  7. #7
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Question about ftp using Qt

    Quote Originally Posted by lni View Post
    QString content = reply->readAll();
    That does an uncontrolled 8-bit encoding to 16-bit unicode conversion, usually not something you want to do when processing XML. The XML document usually has a processing instruction for the correct encoding and the XML parsers react to that.

    Which XML parser are you using?

    Cheers,
    _

  8. #8
    Join Date
    Dec 2006
    Posts
    426
    Thanks
    8
    Thanked 18 Times in 17 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Question about ftp using Qt

    I am now pretty sure QNetworkReply append "\n" in between chunk of data (not all files though).

    I switch to QByteArray, the same thing happens.


    It complains:

    ERROR: code = 3 , what = "Expected '>', but got '[a-zA-Z]'."

    Here is part of the code:

    Qt Code:
    1. QByteArray content = reply->readAll();
    2.  
    3. QFile file( filename );
    4. file.open( QIODevice::WriteOnly );
    5. file.write( content );
    6.  
    7. // parse the file using QXmlStreamReader
    8. QXmlStreamReader reader( content );
    9. ...
    To copy to clipboard, switch view to plain text mode 

    I look at the file, some of the xml tag is broken into 2 lines.

    There are only English characters in the content. No other language.


    And I hit another problem: I submit a job to ftp 300 files, one of the files doesn't exist, it emits error code 203 (ContentNotFoundError). This is fine. But immediately, all remain files got 201 error code (ContentAccessDenied).

    If I remove the bad files, the ftp runs without problem. It get the files. As soon as I put back the non-existing file, 203 is emitted, and immediately the rest files got 201, and job stops.

    I am using Qt 4.8.1 under CentOS.

    PS. I Just google search, and found someone is having the same problem: http://www.qtforum.org/article/33629...essdenied.html
    Last edited by lni; 18th March 2014 at 10:24.

  9. #9
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Question about ftp using Qt

    Very strange.

    You could alternatively try to use QFtp.

    Cheers,
    _

  10. #10
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Question about ftp using Qt

    Quote Originally Posted by lni View Post
    And I hit another problem: I submit a job to ftp 300 files, one of the files doesn't exist, it emits error code 203 (ContentNotFoundError). This is fine. But immediately, all remain files got 201 error code (ContentAccessDenied).

    If I remove the bad files, the ftp runs without problem. It get the files. As soon as I put back the non-existing file, 203 is emitted, and immediately the rest files got 201, and job stops.
    That may be the proper behavior of the ftp server you are connecting to.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  11. #11
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Question about ftp using Qt

    I am now pretty sure QNetworkReply append "\n" in between chunk of data (not all files though).
    Until you demonstrate that the server is not sending these newline characters I am going to assume you are mistaken. If this was a normal behaviour of QNetworkReply on FTP links this would not bode well for lots of Qt FTP usage and the bug tracker would be running hot.

    I just tested fetching a few dozen XML files without a byte out of place (compared byte for byte with version gathered by rsync):
    Qt Code:
    1. #include <QtCore>
    2. #include <QtNetwork>
    3.  
    4. int main(int argc, char **argv)
    5. {
    6. QCoreApplication app(argc, argv);
    7.  
    8. const QStringList fileList = QStringList()
    9. << "assistant/metadata.xml"
    10. << "qtsvg/metadata.xml"
    11. << "qtopenvg/metadata.xml"
    12. << "qtphonon/metadata.xml"
    13. << "qt3support/metadata.xml"; // ... plenty more like these
    14.  
    15. QNetworkAccessManager manager;
    16.  
    17. QEventLoop eventLoop;
    18.  
    19. QObject::connect(&manager, SIGNAL(finished(QNetworkReply*)), &eventLoop, SLOT(quit()));
    20.  
    21. foreach (const QString& file, fileList ) {
    22.  
    23. QUrl url("ftp://mirror.internode.on.net/pub/gentoo-portage/dev-qt/" + file);
    24. url.setUserName( "anonymous" );
    25. url.setPassword( "anon@example.com" );
    26. QNetworkReply *reply = manager.get( QNetworkRequest( url ) );
    27.  
    28. /// block until each file is finished, how do I set timeout in the next line?
    29. eventLoop.exec();
    30.  
    31. /// get the reply content
    32. qDebug() << file << "Error" << reply->error();
    33. QByteArray data = reply->readAll();
    34. QString outFileName(file);
    35. QFile out(outFileName.replace("/", "_"));
    36. if (out.open(QIODevice::WriteOnly)) {
    37. out.write(data);
    38. out.close();
    39. }
    40.  
    41. reply->deleteLater();
    42. }
    43. return 0;
    44. }
    To copy to clipboard, switch view to plain text mode 

    For the record:
    • QNetworkAccessManager only executed a single FTP login (USER/PASS).
    • If a file did not exist I got the same behaviour as you did on subsequent files. It seems that QNetworkAccessManager closed the TCP connection on the FTP 550 response and did not try to reopen it for the later ones. This might be a bug.

  12. #12
    Join Date
    Dec 2006
    Posts
    426
    Thanks
    8
    Thanked 18 Times in 17 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Question about ftp using Qt

    The file size I try to ftp is around 10,000 byte counts, if this information is helpful. Your sample xml file size perhaps is too small (my random thought).

    I didn't block each file, instead I submit all ftp jobs, and then wait until all finish or timeout.

    However, it is more serious for 201 error caused by 203 error. I switch to Qt 5.2, same problem exists.

    Qt Code:
    1. #include <QtCore>
    2. #include <QtNetwork>
    3. #include <QDebug>
    4.  
    5. int main(int argc, char **argv)
    6. {
    7. QCoreApplication app(argc, argv);
    8.  
    9. QNetworkAccessManager manager;
    10.  
    11. QEventLoop eventLoop;
    12.  
    13. QObject::connect(&manager, SIGNAL(finished(QNetworkReply*)), &eventLoop, SLOT(quit()));
    14.  
    15. QList<QNetworkReply*> replies;
    16.  
    17. int loops = 200;
    18. for ( int idx = 0; idx < loops; idx++ ) {
    19.  
    20. /// let's ftp same file 200 times and compare them
    21. /// (But I just got first file, why?)
    22. QUrl url( "ftp://mirror.internode.on.net/pub/gentoo-portage/dev-qt/assistant/metadata.xml" );
    23. url.setUserName( "anonymous" );
    24. url.setPassword( "anon@example.com" );
    25. replies << manager.get( QNetworkRequest( url ) );
    26.  
    27. }
    28.  
    29. /// you need to set time out before exec is call
    30. /// allow 60 seconds timeout for each ftp
    31. QTimer::singleShot( loops * 60 * 1000, &eventLoop, SLOT( quit() ) );
    32.  
    33. /// block until all files area finished
    34. eventLoop.exec();
    35.  
    36. qDebug() << "done";
    37.  
    38. QByteArray ba0 = replies.at( 0 )->readAll();
    39. qDebug() << ba0;
    40.  
    41. for ( int idx = 1; idx < loops; idx++ ) {
    42. QByteArray ba = replies.at( idx )->readAll();
    43. if ( ba0.size() != ba.size() ) {
    44. qDebug() << idx << ": Size not equal";
    45. qDebug() << ba;
    46. break;
    47. }
    48. }
    49.  
    50.  
    51. return 0;
    52. }
    To copy to clipboard, switch view to plain text mode 

Similar Threads

  1. css question
    By Hardstyle in forum Newbie
    Replies: 1
    Last Post: 29th June 2010, 05:29
  2. Question regarding QT ui
    By bostero22 in forum Qt Programming
    Replies: 3
    Last Post: 5th June 2010, 18:02
  3. A question
    By Dante in forum Qt for Embedded and Mobile
    Replies: 3
    Last Post: 12th March 2009, 20:11
  4. MVC question
    By ^NyAw^ in forum Qt Programming
    Replies: 3
    Last Post: 18th May 2007, 19:45

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.