Results 1 to 7 of 7

Thread: Background Question about QTcpSocket

  1. #1
    Join Date
    Sep 2007
    Posts
    3
    Thanks
    2
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11

    Default Background Question about QTcpSocket

    Hi,

    I wonder if anybody here knows of some background information about how something like the QtTcpSocket class works works with the event loop? The concept I'm trying to wrap my brain around is how to implement something like the readyRead() signal, respectively make sure that it's promptly emitted when there is data available. I've tried to look at the source, but it's a pretty bewildering heap of different classes, definitely not so easy to see through.

    I guess the fundamental question could be phrased in even more generic terms: How does the main loop, in a single threaded application, ensure that every class can emit its signals when it decides it needs too? I've looked at a fair number of documents about event-driver programming, but haven't found this particular issue addressed anywhere. The common assumption in introductory texts seems to be that the external events originate in a single place, e.g. from the GUI API, e.g. key press, mouse click etc., and it's the main loop / event handler that collects them.

    However, in the context of a concrete Qt example - e.g. QTcpSocket - you just instantiate this object, connect it's signals and more or less forget about it. And when the time comes it emits a readyRead signal sort of on its own. I'd have thought that it might be implemented with a timer inside the QSocket object, but I can't find any use of QTimer in the networking source code for the life of me, at least not pertaining to socket read.

    The background is of course that I want to learn how to write my own classes that exhibit this sort of behavior, i.e. waiting for some external resource to become ready (without blocking the event loop) and then emit a signal when it finally does.

    I feel right stupid because it seems this should somehow be obvious to me, but I just can't figure it out Maybe just a little shove in the right direction is needed...

    many thanks
    -stefan

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Background Question about QTcpSocket

    Event dispatcher holds a list of all QSocketNotifiers and it simply activates them at the Right Time(tm). Socket notifiers are responsible for checking whether there is any data available using non-blocking I/O and functions like select(2). On the other hand there's also QFileSystemWatcher, which spawns a new thread responsible for monitoring. The third solution, as you already have mentioned, is to use a QTimer to implement polling.

  3. The following user says thank you to jacek for this useful post:

    sm3.142 (27th September 2007)

  4. #3
    Join Date
    Sep 2007
    Posts
    3
    Thanks
    2
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11

    Thumbs up Re: Background Question about QTcpSocket

    Aha. I think I get it - sort of. Thanks for the hint, jacek. So in summery, these are the three strategies to implement such behaviour:

    1) Separate thread with or without its own event loop
    2) Qtimer based polling
    3) Directly integrating with the event loop like QSocketNotifier does.

    I wonder however, if the third strategy is even feasible without customizing the event loop itself. In a nutshell, how would you go about doing that?

  5. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Background Question about QTcpSocket

    Quote Originally Posted by sm3.142 View Post
    I wonder however, if the third strategy is even feasible without customizing the event loop itself. In a nutshell, how would you go about doing that?
    You can use QAbstractEventDispatcher to plug into the event loop. On Unices by default Qt uses Glib event loop, so you can use Glib mechanisms as well.

  6. The following user says thank you to jacek for this useful post:

    sm3.142 (4th October 2007)

  7. #5
    Join Date
    Sep 2007
    Posts
    14
    Thanks
    5
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Default Re: Background Question about QTcpSocket

    The Timer based polling scheme sounds a lot more complex than what is needed.

    All I really needed to do for a TCP client connection was create a QTcpSocket and connect slots to the signals readyread(), error(), stateChanged(), and bytesWritten() to find out about all events of interest.

    The QTcpServer required its own thread, but you can just derive from QThread. Create the server, connect your signals, and call exec() to start message mapping in your run() override.

    I remember there few caveats, but having to periodically poll or reaching into the event loop were not among them.

  8. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Background Question about QTcpSocket

    Quote Originally Posted by AaronMK View Post
    All I really needed to do for a TCP client connection was create a QTcpSocket and connect slots to the signals readyread(), error(), stateChanged(), and bytesWritten() to find out about all events of interest.
    Of course you are right and for simple applications you even don't need a separate thread, but the real question of this thread was "How does the main loop, in a single threaded application, ensure that every class can emit its signals when it decides it needs too?".

  9. #7
    Join Date
    Sep 2007
    Posts
    3
    Thanks
    2
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11

    Default Re: Background Question about QTcpSocket

    I think I understand now how it works in principal. Given the inherent complexity of working with QAbstractEventDispatcher, I've decided to wimp out for now and just go for an operation that blocks with a timeout.

    Since the particular thread can't do much anyway if the resource in question is unavailable, blocking the event loop in chunks is no great hardship as long as it's not blocked indefinitely. The main remaining issue is that while the blocking operation is having a go, you can't immediately stop the thread from a controlling thread by calling the formers QThread::stop() slot. However, it will get around to process the signal eventually, when the blocking operation times out. Net effect is that the whole tear down procedure might be delayed a bit, but that's acceptable for my app.

    Thanks everybody for responding.
    -stefan

Similar Threads

  1. Replies: 5
    Last Post: 24th July 2007, 17:35
  2. Strange QTcpSocket behavior (debugged with Ethereal)
    By mdecandia in forum Qt Programming
    Replies: 23
    Last Post: 28th May 2007, 20:44
  3. Question regarding how to paint after zoom.
    By JonathanForQT4 in forum Qt Programming
    Replies: 2
    Last Post: 26th January 2007, 15:34
  4. background colour
    By kw in forum Qt Programming
    Replies: 6
    Last Post: 11th April 2006, 00:44
  5. Replies: 1
    Last Post: 5th April 2006, 16:44

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.