Results 1 to 15 of 15

Thread: QNetworkAccessManager help needed! Class problem...

  1. #1
    Join Date
    Aug 2011
    Location
    Portugal
    Posts
    34
    Thanks
    15
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Angry QNetworkAccessManager help needed! Class problem...

    Hi,

    I'm trying to download a page from a server to my QT program, but I've been searching ways to do it and they don't really work a lot. I'm not an expert in QT, so be kind

    I ear some suggestions under StackOverflow about how to use QNetworkAccessManager. So here it is my codes so far working (almost) correctly.

    http2.cpp
    Qt Code:
    1. #include "http2.h"
    2.  
    3. http2::http2(QObject *parent) :
    4. QObject(parent)
    5. {
    6. m_manager = new QNetworkAccessManager(this);
    7. connect(m_manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(httpdown(QNetworkReply*)));
    8.  
    9. QNetworkRequest request;
    10. request.setUrl(QUrl("http://localhost/test.php"));
    11. request.setRawHeader("User-Agent", "MyOwnBrowser 1.0");
    12.  
    13. m_manager->get(request);
    14. }
    15.  
    16. void http2::httpdown(QNetworkReply* result)
    17. {
    18.  
    19. QByteArray data= result->readAll();
    20. QString str(data);
    21.  
    22. qDebug() << str;
    23.  
    24. }
    To copy to clipboard, switch view to plain text mode 

    http2.h
    Qt Code:
    1. #ifndef HTTP2_H
    2. #define HTTP2_H
    3.  
    4. #include <QObject>
    5. #include <QDebug>
    6. #include <QtNetwork>
    7. #include <QNetworkReply>
    8.  
    9. class http2 : public QObject
    10. {
    11. Q_OBJECT
    12. public:
    13. explicit http2(QObject *parent = 0);
    14.  
    15. signals:
    16.  
    17. public slots:
    18. void httpdown(QNetworkReply* result);
    19. private:
    20. QNetworkAccessManager* m_manager;
    21.  
    22. };
    23.  
    24. #endif // HTTP2_H
    To copy to clipboard, switch view to plain text mode 
    Now if I call it directly under main.cpp like this:

    main.cpp
    Qt Code:
    1. #include <QtCore/QCoreApplication>
    2. #include "tcpserver.h"
    3. #include "http2.h"
    4.  
    5. int main(int argc, char *argv[])
    6. {
    7. QCoreApplication a(argc, argv);
    8.  
    9. http2 h; // --> Working!!
    10.  
    11. tcpserver mServer;
    12.  
    13. return a.exec();
    14. }
    To copy to clipboard, switch view to plain text mode 
    It works fine. However if I call it inside the tcpserver class like this:

    tcpserver.cpp
    Qt Code:
    1. #include "tcpserver.h"
    2. #include "protocol.h"
    3. #include "http2.h"
    4.  
    5. QTextStream in(stdin);
    6.  
    7. tcpserver::tcpserver(QObject *parent) :
    8. QObject(parent)
    9. {
    10. server = new QTcpServer(this);
    11.  
    12. [ ... Other Server Stuff ... ]
    13.  
    14. http2 h; // --> Not Working :(
    15.  
    16. }
    To copy to clipboard, switch view to plain text mode 

    The signal never happens... http2::httpdown(QNetworkReply* result) is never called, so I don't get the page contents.

    What's wrong? :S

    Thanks.
    Last edited by TCB13; 25th August 2011 at 22:37.

  2. #2
    Join Date
    Aug 2011
    Location
    Portugal
    Posts
    34
    Thanks
    15
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QNetworkAccessManager help needed! Class problem...

    I've a solution to the problem, new code inside the class:

    tcpserver.cpp

    Qt Code:
    1. #include "tcpserver.h"
    2. #include "protocol.h"
    3. #include "http2.h"
    4.  
    5. QTextStream in(stdin);
    6.  
    7. tcpserver::tcpserver(QObject *parent) :
    8. QObject(parent)
    9. {
    10. server = new QTcpServer(this);
    11.  
    12. [ ... Other Server Stuff ... ]
    13.  
    14. // http2 h; // --> OLD non working code
    15. http2 *h = new http2(this); // --> New working
    16.  
    17. }
    To copy to clipboard, switch view to plain text mode 

    This way it works fine.

  3. #3
    Join Date
    Sep 2009
    Location
    UK
    Posts
    2,447
    Thanks
    6
    Thanked 348 Times in 333 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QNetworkAccessManager help needed! Class problem...

    This important thing is: Do you know WHY it didn't work before but does now?

  4. The following user says thank you to squidge for this useful post:

    TCB13 (28th August 2011)

  5. #4
    Join Date
    Aug 2011
    Location
    Portugal
    Posts
    34
    Thanks
    15
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QNetworkAccessManager help needed! Class problem...

    Quote Originally Posted by squidge View Post
    This important thing is: Do you know WHY it didn't work before but does now?
    Well... I guess the problem is I was allocating it locally (instead of dynamically) so when tcpserver ended the other class was ended too.

    Anyway, just a quick question: How can I keep the program waiting for data on http2 before returning to the tcpserver class?

    This should be like a checkpoint were I need to get the data from the server and then keep running the tcpserver and use that data there. (So I can't just create a signal and trow the rest of the tcpserver into a slot...)

    Usually and because I'm a C guy and new to QT/C++ and classes, I would do it like the following code, but it doesn't work...:

    Qt Code:
    1. #include "http2.h"
    2. bool httpdonne = false;
    3. QByteArray finaldata;
    4.  
    5. http2::http2(QObject *parent, QByteArray url, QByteArray data) :
    6. QObject(parent)
    7. {
    8. url.append(data);
    9.  
    10. m_manager = new QNetworkAccessManager(this);
    11. connect(m_manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(httpdown(QNetworkReply*)));
    12.  
    13. QNetworkRequest request;
    14. request.setUrl(QUrl(url));
    15. request.setRawHeader("User-Agent", "MyOwnBrowser 1.0");
    16.  
    17. m_manager->get(request);
    18.  
    19. while ( httpdonne == false ) {
    20.  
    21. }
    22.  
    23. finaldata.append("HTTP: ");
    24. qDebug() << finaldata;
    25.  
    26. }
    27.  
    28. QByteArray http2::httpdown(QNetworkReply* result)
    29. {
    30. QByteArray data = result->readAll();
    31. finaldata = data;
    32. httpdonne = true;
    33. return data;
    34. }
    To copy to clipboard, switch view to plain text mode 

    The code is always stuck in the while loop and nothing else happens.

    Thanks a lot!

  6. #5
    Join Date
    Aug 2011
    Location
    Portugal
    Posts
    34
    Thanks
    15
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QNetworkAccessManager help needed! Class problem...

    some help pleasse!!!

  7. #6
    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: QNetworkAccessManager help needed! Class problem...

    Anyway, just a quick question: How can I keep the program waiting for data on http2 before returning to the tcpserver class?
    I really would advise against that.
    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.


  8. The following user says thank you to wysota for this useful post:

    TCB13 (28th August 2011)

  9. #7
    Join Date
    Aug 2011
    Location
    Portugal
    Posts
    34
    Thanks
    15
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QNetworkAccessManager help needed! Class problem...

    It's the only way I can do it...

    Because that's a checkpoint I need to check if the info is correct, otherwise I need to stop the server and clean some stuff in other classes.

    So I need the program to stay on http2 until it has an answer and then return it to tcpserver class...

    I can't just throw the rest of the program in a new custom slot and activate it by a signal... it doesn't make any sense in the case... it's just "wait for the data, go or quit"

    The solution I made is not working the program is always in the while loop and nothing happens then.

    Thanks.

  10. #8
    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: QNetworkAccessManager help needed! Class problem...

    Quote Originally Posted by TCB13 View Post
    It's the only way I can do it...
    No, it's not, you just have to change the way you think.

    Because that's a checkpoint I need to check if the info is correct, otherwise I need to stop the server and clean some stuff in other classes.
    It doesn't mean your program has to "wait" before "returning to the tcpserver class". Especially since you're in a constructor.

    So I need the program to stay on http2 until it has an answer and then return it to tcpserver class...
    No, you don't. You only need to execute code B after code A is complete. It doesn't mean you have to wait for anything.

    I can't just throw the rest of the program in a new custom slot and activate it by a signal...
    Why not?


    The solution I made is not working the program is always in the while loop and nothing happens then.
    It won't work. You don't have an event loop running, no networking operations can ever complete this way.
    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. The following user says thank you to wysota for this useful post:

    TCB13 (28th August 2011)

  12. #9
    Join Date
    Aug 2011
    Location
    Portugal
    Posts
    34
    Thanks
    15
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Smile Re: QNetworkAccessManager help needed! Class problem...

    Quote Originally Posted by wysota View Post
    No, it's not, you just have to change the way you think.
    Ok, then so help me here a little with logic...

    Quote Originally Posted by wysota View Post
    It doesn't mean your program has to "wait" before "returning to the tcpserver class". Especially since you're in a constructor.

    No, you don't. You only need to execute code B after code A is complete. It doesn't mean you have to wait for anything.

    Why not? - "throw the rest of the program in a new custom slot and activate it by a signal..."
    I'll have to do this type of "checkpoints" when the server starts, a client connects and more other places.. and I don't want to have my QT server interacting directly with my MySQL db.

    If I throw the rest of the tcpserver start in another slot I'll be like "breaking" my program in more parts and I'm adding more complexibility to this. Because usually in C and my AVR/PIC stuff I'm used to run one thing at the time and call a function to do something and the periodically run checks to see if the sockets are still ok and stuff like that. Here it's like everything is happening at the same time..

    Also, each time I will need to do something on the server I will need to "split" the current function into two in order to implement the slot/signal thing. Or can I do that all on the http2 side and leave everything on the tcpserver like it is? - How?

    And.. if a client sends a message that I haven't already checked in the DB he will be able to send another and it will be processed right way. I'm usually more comfortable with the "one thing at a time" approach.

    Quote Originally Posted by wysota View Post
    It won't work. You don't have an event loop running, no networking operations can ever complete this way.
    Got it

    Thanks.

  13. #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: QNetworkAccessManager help needed! Class problem...

    Quote Originally Posted by TCB13 View Post
    I'll have to do this type of "checkpoints" when the server starts, a client connects and more other places.. and I don't want to have my QT server interacting directly with my MySQL db.
    That's ok. But your code doesn't need to be synchronous.

    If I throw the rest of the tcpserver start in another slot I'll be like "breaking" my program in more parts
    That's a good thing.
    and I'm adding more complexibility to this.
    No, that's only your impression. Look at it that you simplify each step of the process by limiting it to a short sequence of operations.

    Because usually in C and my AVR/PIC stuff I'm used to run one thing at the time and call a function to do something and the periodically run checks to see if the sockets are still ok and stuff like that. Here it's like everything is happening at the same time..
    Yes. You are used to synchronous approach and here is an asynchronous approach. Synchronous approach wastes too much resources, asynchronous is better (however it seems more complicated if you're not used to it).

    Also, each time I will need to do something on the server I will need to "split" the current function into two in order to implement the slot/signal thing.
    That's not entirely correct but it is better to stick to such approach if you don't feel confident with Qt. One method triggers a request and another handles the response. You can write a simple dispatcher method that will handle all responses by calling appropriate methods.

    And.. if a client sends a message that I haven't already checked in the DB he will be able to send another and it will be processed right way.
    It depends how you implement it. The proper approach would be to block the user interface for the duration of executing the request.
    I'm usually more comfortable with the "one thing at a time" approach.
    Unfortunately it makes your user interface freeze and there is no way to abort an already running request.
    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.


  14. The following user says thank you to wysota for this useful post:

    TCB13 (28th August 2011)

  15. #11
    Join Date
    Aug 2011
    Location
    Portugal
    Posts
    34
    Thanks
    15
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Smile Re: QNetworkAccessManager help needed! Class problem...

    Quote Originally Posted by wysota View Post
    That's not entirely correct but it is better to stick to such approach if you don't feel confident with Qt. One method triggers a request and another handles the response. You can write a simple dispatcher method that will handle all responses by calling appropriate methods.
    I do have interest in learning what QT has to offer. I see some stuff really powerful like having a signal calling a slot each time there's data available to read in the socket instead of running a loop checking for available data all the time... I see that like an interrupt of a microcontroller where a small function is called to handle a state.

    Quote Originally Posted by wysota View Post
    It depends how you implement it. The proper approach would be to block the user interface for the duration of executing the request.
    In this case I was talking about the TCP Server clients... for instance if I'm checking data on the server using a php get/post on the meanwhile the client in the socket will be able to send another message that will be processed right way. In a security point of view I guess this have a lot of leaks...

    So tell me... my http2 code is this:

    Qt Code:
    1. #include "http2.h"
    2.  
    3. http2::http2(QObject *parent, QByteArray url, QByteArray data) :
    4. QObject(parent)
    5. {
    6. url.append(data);
    7.  
    8. m_manager = new QNetworkAccessManager(this);
    9. connect(m_manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(httpdown(QNetworkReply*)));
    10.  
    11. QNetworkRequest request;
    12. request.setUrl(QUrl(url));
    13. request.setRawHeader("User-Agent", "MyOwnBrowser 1.0");
    14.  
    15. m_manager->get(request);
    16.  
    17.  
    18. }
    19.  
    20. QByteArray http2::httpdown(QNetworkReply* result)
    21. {
    22. result->deleteLater();
    23. QByteArray data = result->readAll();
    24.  
    25. return data;
    26. }
    To copy to clipboard, switch view to plain text mode 

    Can I have/move this:
    Qt Code:
    1. connect(m_manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(httpdown(QNetworkReply*)));
    To copy to clipboard, switch view to plain text mode 

    Directly in my tcpserver? and move the httpdown to there as well? in order to use it to run the next code in the program?

    Thanks.


    Added after 1 8 minutes:



    Can I have/move this:
    Qt Code:
    1. connect(m_manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(httpdown(QNetworkReply*)));
    To copy to clipboard, switch view to plain text mode 

    Directly in my tcpserver? and move the httpdown to there as well? in order to use it to run the next code in the program?

    Thanks.
    Yep, I changed some stuff and seems like I can..
    But this is the way I should do it?

    Qt Code:
    1. tcpserver::tcpserver(QObject *parent) :
    2. QObject(parent)
    3. {
    4. server = new QTcpServer(this);
    5.  
    6. [I] [ ... Server Config and Start Stuff ... ][/I]
    7.  
    8. http2 *h = new http2(this,"http://localhost/test.php","?pag=1");
    9.  
    10. connect(h->m_manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(httpdown(QNetworkReply*)));
    11.  
    12. }
    13.  
    14. void tcpserver::httpdown(QNetworkReply* result)
    15. {
    16. result->deleteLater();
    17. QByteArray data = result->readAll();
    18.  
    19. qDebug() << data;
    20.  
    21. h->deleteLater();
    22.  
    23. }
    To copy to clipboard, switch view to plain text mode 

    Little problem... It works fine but if I add h->deleteLater(); Do I have to delete it or not? I'm already out of the tcpserver::tcpserver so in my experience with QT "h" is not available anymore...

    Do I need to disconnect the signal... because if I want to do more http requests I'll have to connect finished(QNetworkReply*) to another slot... or my program would be going back.

    Thanks!
    Last edited by TCB13; 27th August 2011 at 21:36.

  16. #12
    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: QNetworkAccessManager help needed! Class problem...

    Quote Originally Posted by TCB13 View Post
    In this case I was talking about the TCP Server clients... for instance if I'm checking data on the server using a php get/post on the meanwhile the client in the socket will be able to send another message that will be processed right way. In a security point of view I guess this have a lot of leaks...
    I don't get your point. This situation can happen regardless if your calls are synchronous or not. Synchronous calls are not the same as atomic calls. In either case you need to implement transactions in your system otherwise you'll have race conditions (or your server will be totally exposed to DOS attacks if it can handle only one client at a time).


    As for your code... doing "stuff" in constructors is usually a sign of a bad design. Sending a request from a constructor is a wrong approach in 99% of the cases. You really don't need to know if a component is entitled to do something to construct it.
    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.


  17. #13
    Join Date
    Aug 2011
    Location
    Portugal
    Posts
    34
    Thanks
    15
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QNetworkAccessManager help needed! Class problem...

    Quote Originally Posted by wysota View Post
    I don't get your point. This situation can happen regardless if your calls are synchronous or not. Synchronous calls are not the same as atomic calls. In either case you need to implement transactions in your system otherwise you'll have race conditions (or your server will be totally exposed to DOS attacks if it can handle only one client at a time).

    As for your code... doing "stuff" in constructors is usually a sign of a bad design. Sending a request from a constructor is a wrong approach in 99% of the cases. You really don't need to know if a component is entitled to do something to construct it.
    hm... Since I'm no expert in this "programming style" can you make an example based in my code about how it should be done?

    Thanks for everything.

  18. #14
    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: QNetworkAccessManager help needed! Class problem...

    I suggest you try and do it yourself. If I give you such an example, you will probably treat it as a template and use it everywhere else even if it doesn't fit a particular use case. The general steps are always:
    1. construct objects
    2. schedule a delayed call to initialize internal mechanisms of the application (using a 0-timeout timer or QMetaObject::invokeMethod())
    3. enter the event loop (QCoreApplication::exec())

    Then treat the current state as a default idle state of your application. If you want the application to do something, start constructing objects and executing methods that will eventually cause other methods to be called that will do their job and return the application to the "idle" state.
    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.


  19. The following user says thank you to wysota for this useful post:

    TCB13 (28th August 2011)

  20. #15
    Join Date
    Aug 2011
    Location
    Portugal
    Posts
    34
    Thanks
    15
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QNetworkAccessManager help needed! Class problem...

    Quote Originally Posted by wysota View Post
    I suggest you try and do it yourself. If I give you such an example, you will probably treat it as a template and use it everywhere else even if it doesn't fit a particular use case. The general steps are always:
    1. construct objects
    2. schedule a delayed call to initialize internal mechanisms of the application (using a 0-timeout timer or QMetaObject::invokeMethod())
    3. enter the event loop (QCoreApplication::exec())

    Then treat the current state as a default idle state of your application. If you want the application to do something, start constructing objects and executing methods that will eventually cause other methods to be called that will do their job and return the application to the "idle" state.
    Hi, well I'll give it a try, I've been reading about the even loop itself to understand some things.

    Thanks for all the help

Similar Threads

  1. Replies: 8
    Last Post: 19th April 2011, 08:17
  2. QNetworkAccessManager problem instantiating
    By hojoff79 in forum Qt Programming
    Replies: 8
    Last Post: 9th February 2011, 05:59
  3. Replies: 7
    Last Post: 2nd September 2010, 20:42
  4. qnetworkaccessmanager problem!
    By novamaster in forum Qt Programming
    Replies: 6
    Last Post: 7th August 2010, 12:46
  5. help needed to write a render class
    By franco.amato in forum Qt Programming
    Replies: 9
    Last Post: 1st June 2010, 23:07

Tags for this Thread

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.