Results 1 to 12 of 12

Thread: Socket + thread problem

  1. #1
    Join Date
    May 2010
    Posts
    46
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Windows

    Default Socket + thread problem

    Hi,
    I have a multithread application with 1 server and multiple client.

    This is my QTCode:

    Qt Code:
    1. #ifndef MESSAGETHREAD_H
    2. #define MESSAGETHREAD_H
    3.  
    4. #include <QThread>
    5. #include <QTcpSocket>
    6. #include <QTcpServer>
    7.  
    8. class MessageThread : public QThread
    9. {
    10. Q_OBJECT
    11.  
    12. public:
    13. MessageThread();
    14.  
    15. void run();
    16.  
    17. public slots:
    18. void newMessConnection();
    19.  
    20. signals:
    21. void error(QTcpSocket::SocketError socketError);
    22.  
    23. private:
    24. QTcpServer* messageSrv;
    25. QString text;
    26. };
    27.  
    28. #endif
    To copy to clipboard, switch view to plain text mode 

    Implementation:

    Qt Code:
    1. #include "MessageThread.h"
    2.  
    3. #include <QtNetwork>
    4.  
    5.  
    6. #define IPADDRESS "192.168.1.160"
    7.  
    8. MessageThread::MessageThread()
    9. {
    10. }
    11.  
    12. void MessageThread::run()
    13. {
    14. QTcpServer* messageServer = new QTcpServer;
    15. messageSrv = messageServer;
    16. connect(messageServer, SIGNAL(newConnection()), this, SLOT(newMessConnection()));
    17.  
    18. QHostAddress xIpAddress;
    19. quint16 port;
    20.  
    21. xIpAddress.setAddress(IPADDRESS);
    22. port = 2223;
    23.  
    24. if(!messageServer->listen(xIpAddress, port))
    25. {
    26. printf("\n Communication Manager.d: Unable to start the server.");
    27. messageServer->close();
    28. }
    29.  
    30. if (messageServer->isListening())
    31. {
    32. printf("\n Message Server initialized");
    33. }
    34. exec();
    35.  
    36.  
    37. }
    38.  
    39. void MessageThread::newMessConnection()
    40. {
    41. printf("\n Message server: send data....");
    42. QTcpSocket* connection = messageSrv->nextPendingConnection();
    43. QString test = "test data";
    44.  
    45. QByteArray block;
    46. QDataStream out(&block, QIODevice::WriteOnly);
    47. out.setVersion(QDataStream::Qt_4_0);
    48. out << (quint16)0;
    49. out << test;
    50. out.device()->seek(0);
    51. out << (quint16)(block.size() - sizeof(quint16));
    52. connection->write(block);
    53.  
    54. }
    To copy to clipboard, switch view to plain text mode 


    When I create this thread the line "connection->write(block);" show me this error:

    QObject: Cannot create children for a parent that is in a different thread.
    Parent's thread is MessageThread, current thread is QThread.


    How i can solve it?
    Can anyone help me please?

    Bye

  2. #2
    Join Date
    Jan 2006
    Location
    Belgium
    Posts
    1,938
    Thanked 268 Times in 268 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Wiki edits
    20

    Default Re: Socket + thread problem

    Step 1: do not use threading for socket communication unless you absolutely need to use blocking functions.
    Why do you think you need threads?

    Ok, now what is wrong with your code. At first sight nothing, but in the background there's a huge problem.
    Let's break up your code:

    Qt Code:
    1. class MessageThread : public QThread
    2. {
    3. ...
    4. };
    To copy to clipboard, switch view to plain text mode 

    Your MessageThread class is a subclass of QThread.
    A QThread subclass is NOT a new thread. Any MessageThread object lives in the main GUI thread. Keep that in mind for the next lines of code.

    Qt Code:
    1. public slots:
    2. void newMessConnection();
    3.  
    4. signals:
    5. void error(QTcpSocket::SocketError socketError);
    To copy to clipboard, switch view to plain text mode 

    These signals and slots, which you define in your QThread subclass are emitted and called inside the main GUI thread since the QThread object lives in the main gui thread. Try to understand this when we look at the next few lines of code.

    Qt Code:
    1. void MessageThread::run()
    2. {
    3. QTcpServer* messageServer = new QTcpServer;
    4. messageSrv = messageServer;
    5. connect(messageServer, SIGNAL(newConnection()), this, SLOT(newMessConnection()));
    6. }
    To copy to clipboard, switch view to plain text mode 

    The code in the run() function is being run in a separate thread. So far that's a good idea. You define a new QTcpServer object inside this new thread. So far that's also good. You might want to write messageSrv = new QTcpServer directly though. The problems begin with the connection of the signal and the slot.

    The signal newConnection() is being emitted in another thread than the slot newMessConnection(). The slot newMessConnection lives in the main gui thread. Ok, so far that's not a big problem as you want to have some feedback to your main thread.

    However, let's look what happens in the slot itself:

    Qt Code:
    1. void MessageThread::newMessConnection()
    2. {
    3. QTcpSocket* connection = messageSrv->nextPendingConnection();
    4. }
    To copy to clipboard, switch view to plain text mode 

    The connection object is a huge problem. Remember, as I already mentioned several times, the newMessConnection lives in the main gui thread!!!. BUT, messageSrv points to an object in another thread!!!
    This is an error!.

    This is the exact reason why you get the following error:
    Qt Code:
    1. QObject: Cannot create children for a parent that is in a different thread.
    To copy to clipboard, switch view to plain text mode 

    Solution, in pseudo code:

    Qt Code:
    1. class MyConnection : public QObject
    2. {
    3. Q_OBJECT
    4.  
    5. public slots:
    6. void newConnection();
    7.  
    8. signals:
    9. void error();
    10. };
    11.  
    12. Then when you use your connection:
    13.  
    14. MyConnection *connection = new MyConnection;
    15. connect(connection, SIGNAL(error()), this, SLOT(handleError()));
    16.  
    17. QThread *connectionThread = new QThread;
    18.  
    19. connection->moveToThread(connectionThread);
    To copy to clipboard, switch view to plain text mode 

    Edit: Since this question gets asked a lot and since the Qt documentation, at the moment, isn't very clear on this complexity, I'll write a wiki tutorial on threading and sockets this week.
    Last edited by tbscope; 12th July 2010 at 11:26.

  3. #3
    Join Date
    May 2010
    Posts
    46
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Socket + thread problem

    This is my pboject:

    suppose that I have some different application A, B, C....
    A is the main programm, run and listening in a specific port.

    B connect to A. I want than A can be able to communicate with B and receive some information about B. Then I want that I can be able to create another channel of communication (a new socket that work in another port that A tell to B).

    But at the same time I want that A can be able to receive other request of connections for example from C o D.

    What do you think about this architecture? Is correct use some different thread to the registration step e one different thread to communicate??

    Bye, Thanks

  4. #4
    Join Date
    Apr 2010
    Location
    Rostov-na-Donu, Russia
    Posts
    153
    Thanks
    2
    Thanked 26 Times in 23 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Socket + thread problem

    Answering for your first question: you can simply do this:
    Qt Code:
    1. MessageThread::MessageThread()
    2. {
    3. moveToThread( this );
    4. }
    To copy to clipboard, switch view to plain text mode 

  5. #5
    Join Date
    Jan 2006
    Location
    Belgium
    Posts
    1,938
    Thanked 268 Times in 268 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Wiki edits
    20

    Default Re: Socket + thread problem

    No, DO NOT do what the previous poster said!!!

  6. #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: Socket + thread problem

    Quote Originally Posted by borisbn View Post
    Answering for your first question: you can simply do this:
    Qt Code:
    1. MessageThread::MessageThread()
    2. {
    3. moveToThread( this );
    4. }
    To copy to clipboard, switch view to plain text mode 
    Tell me, what will happen with the following code:

    Qt Code:
    1. class Thread : public QThread {
    2. Thread() : QThread() {
    3. moveToThread(this);
    4. }
    5. protected:
    6. void customEvent(QEvent *e) {
    7. qDebug() << "Custom event" << QThread::currentThreadId ();
    8. }
    9. };
    10. //...
    11. Thread thread;
    12. QApplication::postEvent(&thread, new QEvent(QEvent::User));
    13. // assuming no thread.start() anywhere here
    To copy to clipboard, switch view to plain text mode 

    Will the custom event be delivered or not? And if it will then in context of which thread will it execute?
    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.


  7. #7
    Join Date
    Apr 2010
    Location
    Rostov-na-Donu, Russia
    Posts
    153
    Thanks
    2
    Thanked 26 Times in 23 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Socket + thread problem

    Easy, easy, tbscope...
    Why not ? I did moveToThread( this ) and it worked. Please say, what is wrong with that ?
    Thanks.

  8. #8
    Join Date
    Jul 2009
    Location
    Enschede, Netherlands
    Posts
    462
    Thanked 69 Times in 67 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Socket + thread problem

    Horse sense is the thing that keeps horses from betting on people. --W.C. Fields

    Ask Smart Questions

  9. #9
    Join Date
    Apr 2010
    Location
    Rostov-na-Donu, Russia
    Posts
    153
    Thanks
    2
    Thanked 26 Times in 23 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Socket + thread problem

    Quote Originally Posted by wysota View Post
    // assuming no thread.start() anywhere here
    ok, if you will not start the thread, then you will not process events in it. In your example ( but without moveToThread ) events will be processed in main thread, but topic starter ( if I understand correctly ) wanted to process events in separate thread. To do this hi should move objects, that generates events, to that tread. I suggested to move whole object Thread to thread. In this way all it's children will be it thread.

  10. #10
    Join Date
    Jan 2006
    Location
    Belgium
    Posts
    1,938
    Thanked 268 Times in 268 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Wiki edits
    20

    Default Re: Socket + thread problem

    Quote Originally Posted by borisbn View Post
    Easy, easy, tbscope...
    Ohh, sorry, I didn't want to insult you.
    Text messages are notoriously difficult to get the emotions from.

    It's documented that it is wrong to use moveToThread on the QThread, and if you think about it a little bit you know why it doesn't make sense to do so. See the posts above.

    You are correct though that the whole object needs to be moved to another thread. But only the object, not QThread.
    Therefor you need to create your own object and then use moveToThread on that object to move it to another thread.
    QThread needs to live in the main thread and act as a translator/manager/whatever... between the main thread and the object in the other thread.

  11. #11
    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: Socket + thread problem

    Quote Originally Posted by borisbn View Post
    ok, if you will not start the thread, then you will not process events in it. In your example ( but without moveToThread ) events will be processed in main thread, but topic starter ( if I understand correctly ) wanted to process events in separate thread. To do this hi should move objects, that generates events, to that tread. I suggested to move whole object Thread to thread. In this way all it's children will be it thread.
    There are two things here:
    1. Why move the QThread object to another thread instead of creating a separate object and moving THAT to the thread or better yet creating that object in the thread itself?
    2. Why move the QThread object to another thread before the thread is actuallys started?

    There is also point 3:
    - Why use threads here at all?
    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.


  12. #12
    Join Date
    May 2010
    Posts
    46
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Socket + thread problem

    Ok, I think that I have solve my problem. I have use the first replay of tbscope that is the same that I have read here:

    http://labs.trolltech.com/blogs/2010...doing-it-wrong

    I think that thread's implementations isn't clear, for example if you read " Threaded Fortune Server Example" you can see that FortuneServer subclass QThread and it can be create confusion.

    thanks all fro the replay,

    See you, Dax

Similar Threads

  1. socket & thread
    By prashant in forum Qt Programming
    Replies: 2
    Last Post: 2nd December 2009, 10:09
  2. thread with socket?
    By triperzonak in forum Qt Programming
    Replies: 6
    Last Post: 25th September 2008, 16:21
  3. Socket on a Thread
    By ^NyAw^ in forum Qt Programming
    Replies: 2
    Last Post: 7th May 2008, 15:56
  4. Thread, Timer and Socket. Comuication problem
    By ^NyAw^ in forum Qt Programming
    Replies: 6
    Last Post: 17th January 2008, 16:48
  5. How to write on a socket in another thread?
    By Valheru in forum Qt Programming
    Replies: 7
    Last Post: 12th October 2006, 10:52

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.