Results 1 to 4 of 4

Thread: QTcpSockets and QThreads

  1. #1
    Join Date
    Jun 2006
    Location
    Sweden
    Posts
    99
    Thanks
    11
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default QTcpSockets and QThreads

    I'm trying to write a multithreaded chat program based on the threaded fortune server example.

    The setup:
    My first step was to prevent the thread from terminating immediately, a while loop in the Thread::run() method, as shown below, did this nicely...or so i thought.

    Qt Code:
    1. void Thread::closeConnectionNow()
    2. {
    3. socket->disconnectFromHost();
    4. socket->waitForDisconnect(1);
    5. }
    6.  
    7. void Thread::closeConnection()
    8. {
    9. socket->deleteLater();
    10. }
    11.  
    12. void Thread::readData()
    13. {
    14. //code for reading data
    15. }
    16.  
    17. void Thread::run()
    18. {
    19. ...
    20. connect(socket, SIGNAL(readyRead()), this, SLOT(readData()));
    21. connect(socket, SIGNAL(disconnected()), this, SLOT(closeConnection()));
    22. while (socket->state() == QAbstractSocket::ConnectedState)
    23. socket->waitForDisconnected(-1);
    24. }
    To copy to clipboard, switch view to plain text mode 

    note: The closeConnectionNow()-method is available to the thread's parent.

    What works:
    The thread runs, and waits in the loop while still answering readyRead() signals properly. When the client closes the connection, the disconnected() signal is received correctly and the thread exits.

    What doesn't work:
    Calling the closeConnectionNow()-method from the parent thread does not have any effect. It executes but the socket refuses to close.

    Have i missed some critical step that would allow the thread to close the connection?

    Perhaps the solution i've chosen is flawed to begin with and i should find a single-threaded solution instead?

    Any input is appreciated! Thanks in advance!

  2. #2
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: QTcpSockets and QThreads

    Quote Originally Posted by TheRonin
    What doesn't work:
    Calling the closeConnectionNow()-method from the parent thread does not have any effect. It executes but the socket refuses to close.
    Sounds like you are calling the function directly from another thread. This is a no no. So basically, I'm afraid you have two parallel executions going in the code above: 1) the actual thread execution is blocked in the end of the run()-method at QSocket::waitForDisconnected() and 2) another thread (where closeConnectionNow() is called from) executes closeConnectionNow().

    You might want to consider entering to an event loop in the thread and using signals and slots and a queued connection instead of a direct call from another thread.

    So the code should look more like this:
    Qt Code:
    1. // create a queued connection between the thread and the parent
    2. Thread* thread = new Thread(this);
    3. connect(this, SIGNAL(somethingHappened()), thread, SLOT(closeConnection()), Qt::QueuedConnection);
    4.  
    5. // ..and when you would call closeConnectionNow(), now you will just emit somethingHappened() instead
    6. // remember to declare somethingHappened() as a signal
    7. emit somethingHappened();
    8.  
    9. // declare Thread::closeConnectionNow() as a slot
    10. void Thread::closeConnectionNow()
    11. {
    12. socket->disconnectFromHost();
    13. }
    14.  
    15. void Thread::run()
    16. {
    17. ...
    18. connect(socket, SIGNAL(readyRead()), this, SLOT(readData()));
    19. connect(socket, SIGNAL(disconnected()), this, SLOT(closeConnection()));
    20. exec(); // enter to the event loop
    21. }
    To copy to clipboard, switch view to plain text mode 
    J-P Nurmi

  3. #3
    Join Date
    Jun 2006
    Location
    Sweden
    Posts
    99
    Thanks
    11
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QTcpSockets and QThreads

    Thanks for the tip! I changed the structure and now it works fine!

    Just one thing though; when i have more threads running, won't emiting somethingHappened() cause all of them to close?

  4. #4
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: QTcpSockets and QThreads

    Quote Originally Posted by TheRonin
    Just one thing though; when i have more threads running, won't emiting somethingHappened() cause all of them to close?
    Yes it will unless you map the signal somehow to the appropriate thread (check QSignalMapper docs).
    Another a bit simplier way could be to simply pass some identifier number (eg. socket descriptor) as an argument for the signal and then the thread closes connection only if the identifier matches.
    J-P Nurmi

  5. The following user says thank you to jpn for this useful post:

    tpf80 (17th November 2009)

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.