Results 1 to 9 of 9

Thread: QNetworkAccessManager and network errors

  1. #1
    Join Date
    Aug 2008
    Posts
    50
    Thanks
    5
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default QNetworkAccessManager and network errors

    Hello.
    On http://doc.qt.nokia.com/4.7/qnetworkaccessmanager.html is small example:
    Qt Code:
    1. QNetworkRequest request;
    2. request.setUrl(QUrl("http://qt.nokia.com"));
    3. request.setRawHeader("User-Agent", "MyOwnBrowser 1.0");
    4.  
    5. QNetworkReply *reply = manager->get(request);
    6. //if network error occur here - what happens? slotError is called or not?
    7.  
    8. connect(reply, SIGNAL(readyRead()), this, SLOT(slotReadyRead()));
    9. connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
    10. this, SLOT(slotError(QNetworkReply::NetworkError)));
    11. connect(reply, SIGNAL(sslErrors(QList<QSslError>)),
    12. this, SLOT(slotSslErrors(QList<QSslError>)));
    To copy to clipboard, switch view to plain text mode 
    If network error occur in line 6 of code - what happens? Probably slotError will not be triggered. Any suggestions?

  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: QNetworkAccessManager and network errors

    As I understand it, the call to get() queues a request that does not start executing until the event loop is reached. This happens after making all the connections. As a result there can be no error in the location you highlighted.

    Of course, I could be wrong.

  3. #3
    Join Date
    Aug 2008
    Posts
    50
    Thanks
    5
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QNetworkAccessManager and network errors

    Quote Originally Posted by ChrisW67 View Post
    As I understand it, the call to get() queues a request that does not start executing until the event loop is reached. This happens after making all the connections. ...
    So, why http://doc.qt.nokia.com/4.7/qnetwork...nager.html#get not writing about any queue?

    In addition to the above:
    why condition in line 7 is true(when network error occur)?
    Qt Code:
    1. QNetworkRequest request;
    2. request.setUrl(QUrl("http://qt.nokia.com"));
    3. request.setRawHeader("User-Agent", "MyOwnBrowser 1.0");
    4.  
    5. QNetworkReply *reply = manager->get(request);
    6. //if network error occur here - what happens? slotError is called or not?
    7. if(reply->error() != QNetworkReply::NoError)
    8. qDebug("network error!");
    9.  
    10. connect(reply, SIGNAL(readyRead()), this, SLOT(slotReadyRead()));
    11. connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
    12. this, SLOT(slotError(QNetworkReply::NetworkError)));
    13. connect(reply, SIGNAL(sslErrors(QList<QSslError>)),
    14. this, SLOT(slotSslErrors(QList<QSslError>)));
    To copy to clipboard, switch view to plain text mode 

  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: QNetworkAccessManager and network errors

    From the documentation you linked:
    Note: QNetworkAccessManager queues the requests it receives. The number of requests executed in parallel is dependent on the protocol. Currently, for the HTTP protocol on desktop platforms, 6 requests are executed in parallel for one host/port combination.
    This example:
    Qt Code:
    1. #include <QtCore>
    2. #include <QtNetwork>
    3. #include <QDebug>
    4.  
    5. class TestObject: public QObject {
    6. Q_OBJECT
    7. public:
    8. TestObject(QObject *p = 0): QObject(p), reply(0) {
    9. QTimer::singleShot(0, this, SLOT(doIt()));
    10. }
    11. public slots:
    12. void doIt() {
    13. qDebug() << "doIt called";
    14. QNetworkRequest request;
    15. // request.setUrl(QUrl("http://qt.nokia.com"));
    16. // request.setUrl(QUrl("NOSCHEME://qt.nokia.com"));
    17. // request.setUrl(QUrl("ftp://qt.nokia.com"));
    18. // request.setUrl(QUrl("https://site.without.ssl"));
    19. request.setUrl(QUrl("http://RUBBISH.nokia.com"));
    20.  
    21. reply = manager.get(request);
    22.  
    23. // This message is not triggered
    24. if(reply->error() != QNetworkReply::NoError)
    25. qDebug() << "network error!" << reply->error();
    26.  
    27. connect(reply, SIGNAL(readyRead()), this, SLOT(slotReadyRead()));
    28. connect(reply, SIGNAL(finished()), this, SLOT(slotFinished()));
    29. connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
    30. this, SLOT(slotError(QNetworkReply::NetworkError)));
    31. qDebug() << "doIt finished";
    32. }
    33. void slotReadyRead() {
    34. qDebug() << "slotReadyRead";
    35. }
    36. void slotFinished() {
    37. qDebug() << reply->readAll();
    38. reply->deleteLater();
    39. }
    40. void slotError(QNetworkReply::NetworkError e) {
    41. qDebug() << "slotError" << e ;
    42. }
    43. private:
    44.  
    45. QNetworkAccessManager manager;
    46. QNetworkReply *reply;
    47. };
    48.  
    49. int main(int argc, char *argv[])
    50. {
    51. QCoreApplication app(argc, argv);
    52.  
    53. TestObject t;
    54. return app.exec();
    55. }
    56. #include "main.moc"
    To copy to clipboard, switch view to plain text mode 
    Doesn't fail at your debug statement with any of the examples. All the error messages come from the slot code. Some of these should fail immediately so there is no network delay.

    Can you provide an example that does fail?
    Last edited by ChrisW67; 22nd February 2011 at 08:26.

  5. #5
    Join Date
    Aug 2008
    Posts
    50
    Thanks
    5
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QNetworkAccessManager and network errors

    Quote Originally Posted by ChrisW67 View Post
    Can you provide an example that does fail?
    Yes, here:
    Qt Code:
    1. #include <QtCore>
    2. #include <QtNetwork>
    3. #include <QDebug>
    4.  
    5. class TestObject: public QObject {
    6. Q_OBJECT
    7. public:
    8. TestObject(QObject *p = 0): QObject(p), reply(0) {
    9. QTimer::singleShot(0, this, SLOT(doIt()));
    10. }
    11. public slots:
    12. void doIt() {
    13. qDebug() << "doIt called";
    14. QNetworkRequest request;
    15. request.setUrl(QUrl("http://213.251.170.205/~david/index.htm"));
    16.  
    17. reply = manager.get(request);
    18.  
    19. // This message is not triggered
    20. if(reply->error() != QNetworkReply::NoError)
    21. qDebug() << "network error!" << reply->error();
    22.  
    23. connect(reply, SIGNAL(finished()), this, SLOT(slotFinished()));
    24. connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
    25. this, SLOT(slotError(QNetworkReply::NetworkError)));
    26. qDebug() << "doIt finished";
    27. }
    28.  
    29. void slotFinished() {
    30. qDebug() << "slotFinished";
    31. qDebug() << reply->readAll();
    32. reply->deleteLater();
    33.  
    34. //reconnect after 2 seconds
    35. QTimer::singleShot(2000, this, SLOT(doIt()));
    36. }
    37. void slotError(QNetworkReply::NetworkError e) {
    38. qDebug() << "slotError" << e ;
    39. }
    40. private:
    41.  
    42. QNetworkAccessManager manager;
    43. QNetworkReply *reply;
    44. };
    45.  
    46. int main(int argc, char *argv[])
    47. {
    48. QCoreApplication app(argc, argv);
    49.  
    50. TestObject t;
    51. return app.exec();
    52. }
    53. #include "main.moc"
    To copy to clipboard, switch view to plain text mode 
    When my PPP network interface is down, I start example:
    doIt called
    network error! 99
    doIt finished
    [program running but not do enything, not calling slots etc. I shutdown example.]

    PPP network interface is up, I start example:
    doIt called
    doIt finished
    slotFinished
    "<html><body>web contents</body></html>
    "
    [In this moment, I shutdown PPP network interface]
    doIt called
    doIt finished
    [program running but not do enything, not calling slots etc.]

  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: QNetworkAccessManager and network errors

    If you use the finished() signal emitted by QNetworkAccessManager rather than the specific QNetworkReply you could check that the reply was successful in the slot before using the result. The signal connection is done one once, and before any requests are issued thereby eliminating the race condition you have here. You can also check the networkAccessible property of the manager.

  7. #7
    Join Date
    Aug 2008
    Posts
    50
    Thanks
    5
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QNetworkAccessManager and network errors

    Quote Originally Posted by ChrisW67 View Post
    If you use the finished() signal emitted by QNetworkAccessManager rather than the specific QNetworkReply you could check that the reply was successful in the slot before using the result. The signal connection is done one once, and before any requests are issued thereby eliminating the race condition you have here. You can also check the networkAccessible property of the manager.
    Thanks, I will check QNetworkAccessManager::finished(). But in the meantime: What wrong with my code example? Where is the begin of race condidtion?

    Is this it?
    Qt Code:
    1. //...
    2. //reconnect after 2 seconds
    3. QTimer::singleShot(2000, this, SLOT(doIt()));
    4. //...
    To copy to clipboard, switch view to plain text mode 


    Added after 20 minutes:


    I used QNetworkAccessManager::finished(QNetworkReply *):

    Qt Code:
    1. #include <QtCore>
    2. #include <QtNetwork>
    3. #include <QDebug>
    4.  
    5. class TestObject: public QObject {
    6. Q_OBJECT
    7. public:
    8. TestObject(QObject *p = 0): QObject(p)
    9. {
    10. connect(&manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(slotFinished(QNetworkReply *)));
    11. QTimer::singleShot(0, this, SLOT(doIt()));
    12. }
    13. public slots:
    14. void doIt() {
    15. qDebug() << "doIt called";
    16. QNetworkRequest request;
    17. request.setUrl(QUrl("http://213.251.170.205/~david/index.htm"));
    18.  
    19. manager.get(request);
    20.  
    21. qDebug() << "doIt finished";
    22. }
    23.  
    24. void slotFinished(QNetworkReply * reply) {
    25. qDebug() << "slotFinished";
    26. if(reply->error() != QNetworkReply::NoError)
    27. qDebug() << "network error! " << reply->error();
    28. else
    29. qDebug() << reply->readAll();
    30.  
    31. reply->deleteLater();
    32.  
    33. //reconnect after 2 seconds
    34. QTimer::singleShot(2000, this, SLOT(doIt()));
    35. }
    36. private:
    37. QNetworkAccessManager manager;
    38. };
    39.  
    40. int main(int argc, char *argv[])
    41. {
    42. QCoreApplication app(argc, argv);
    43.  
    44. TestObject t;
    45. return app.exec();
    46. }
    47. #include "main.moc"
    To copy to clipboard, switch view to plain text mode 
    But slotFinished is not called when I shutdown network interface.
    Last edited by lukass; 22nd February 2011 at 12:11.

  8. #8
    Join Date
    Aug 2008
    Posts
    50
    Thanks
    5
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QNetworkAccessManager and network errors

    The QNetworkAccessManager::networkAccessible() always return -1(QNetworkAccessManager::UnknownAccessibility).
    So, how can I get signal if network error occur? Can anyone help?

  9. #9
    Join Date
    Aug 2008
    Posts
    50
    Thanks
    5
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QNetworkAccessManager and network errors

    This problem is probably related to:
    http://bugreports.qt.nokia.com/browse/QTBUG-3443

    I found solution. I added timer and function state(), which check connection state:
    Qt Code:
    1. #include <QtCore>
    2. #include <QtNetwork>
    3. #include <QDebug>
    4.  
    5. class TestObject: public QObject {
    6. Q_OBJECT
    7. public:
    8. TestObject(QObject *p = 0): QObject(p) {
    9. conn_check = new QTimer(this);
    10. conn_check->setInterval(30000); //30 seconds
    11. connect(conn_check, SIGNAL(timeout()), SLOT(state()));
    12. connect(&manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(slotFinished(QNetworkReply *)));
    13. QTimer::singleShot(0, this, SLOT(doIt()));
    14. }
    15. public slots:
    16. void doIt() {
    17. qDebug() << "doIt called";
    18. QNetworkRequest request;
    19. request.setUrl(QUrl("http://213.251.170.205/~david/index.htm"));
    20.  
    21. reply = manager.get(request);
    22. conn_check->start();
    23.  
    24. qDebug() << "doIt finished";
    25. }
    26.  
    27. void slotFinished(QNetworkReply * reply) {
    28. conn_check->stop();
    29. qDebug() << "slotFinished";
    30. if(reply->error() != QNetworkReply::NoError)
    31. qDebug() << "network error! " << reply->error();
    32. else
    33. qDebug() << reply->readAll();
    34.  
    35. reply->deleteLater();
    36.  
    37. //reconnect after 2 seconds
    38. QTimer::singleShot(2000, this, SLOT(doIt()));
    39. }
    40.  
    41. void state() {
    42. conn_check->stop();
    43. qDebug() << "isFinished: " << reply->isFinished();
    44. qDebug() << "isRunning: " << reply->isRunning();
    45. if(reply->isFinished())
    46. slotFinished(reply);
    47. else
    48. reply->abort(); //emits finished(/*...*/) signal
    49. }
    50.  
    51. private:
    52. QNetworkAccessManager manager;
    53. QNetworkReply * reply;
    54. QTimer * conn_check;
    55. };
    56.  
    57. int main(int argc, char *argv[]) {
    58. QCoreApplication app(argc, argv);
    59.  
    60. TestObject t;
    61. return app.exec();
    62. }
    63. #include "main.moc"
    To copy to clipboard, switch view to plain text mode 

Similar Threads

  1. Network statistics with QNetworkAccessManager
    By The_Fallen in forum Qt Programming
    Replies: 7
    Last Post: 20th September 2010, 01:01
  2. get network stream with QNetworkAccessManager
    By Remco in forum Qt Programming
    Replies: 0
    Last Post: 26th August 2010, 16:25
  3. Replies: 0
    Last Post: 7th August 2010, 09:55
  4. Replies: 1
    Last Post: 23rd July 2010, 13:10
  5. QNetworkAccessManager get request causing QSslSocket errors
    By Runtime Technologies in forum Qt Programming
    Replies: 5
    Last Post: 29th July 2009, 22:57

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.