Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Strange behaviour of Signal/Slots (QtNetwork) used over QThread

Strange behaviour of Signal/Slots (QtNetwork) used over QThread

Scheduled Pinned Locked Moved General and Desktop
qtnetworkqthreadqeventloopsignal & slot
8 Posts 2 Posters 3.3k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Q Offline
    Q Offline
    QtExchange
    wrote on 23 Mar 2016, 09:14 last edited by QtExchange
    #1

    Hey everyone I need your help

    When implementing a network extension for my main program a strange error occured: When I set the server into listening state I am able to connect with a client but the server never processes SIGNAL(newConnection()) itself and thus I'm unable to work on.

    Has anybody an idea how to solve it ?

    I'm breaking down the code to the most relevant parts.

    Here the content of the .h

    #include <QtNetwork>
    #include <QTcpServer>
    #include <QTcpSocket>
    
    class NetworkEvents: public QThread
    {
    	Q_OBJECT:
    public:
    	QEventLoop *networkLoop;
    	NetworkEvents(QObject *mainObj, QTcpServer* theServer);
    protected:
    	void run();
    private:
    	QTcpServer* server;
    
    public slots:
    	void incommingCnt();
    };
    
    class NetworkSupport: public QObject
    {
    	Q_OBJECT
    public:
    	NetworkSupport(QObject* mainObj);
    private:
    	NetworkEvents* events;
    protected:
    	QTcpServer* server;
    };
    

    Here the content of the .cpp

    NetworkEvents::NetworkEvents(QObject* mainObj, QTcpServer * theServer)
    {
    	networkLoop = new QEventLoop(mainObj);
    	server = theServer;
    	start();
    }
    
    void NetworkEvents::incommingCnt()
    {
    	printf("successfully connected\n");
    }
    
    void NetworkEvents::run()
    {
    	if(server->isListening())
    	{
    			connect(server, SIGNAL(newConnection()), this, SLOT(incommingCnt()));
    			printf("running eventloop\n");
    			networkLoop->exec();
    	}
    }
    
    NetworkSupport::NetworkSupport(QObject *mainObj):QObject(mainObj)
    {
    	server = new QTcpServer(mainObj);
    	server->listen(QHostAdress::Any, 5200);
    	events = new NetworkEvents(mainObj, server);
    	printf("successfully initiated W-LAN communication\n");
    }
    

    NetworkSupport(mainObj) again gets called by the main program. I need to implement the QEventLoop in an extra thread due to interferrences with the main application.

    NB: all the printf()s are executed but the one in incommingCnt()

    Kind Regards

    1 Reply Last reply
    0
    • K Offline
      K Offline
      kshegunov
      Moderators
      wrote on 23 Mar 2016, 09:42 last edited by kshegunov
      #2

      @QtExchange
      Hi,
      You're doing it wrong, on multiple counts.

      Firstly, your objects are all in the main thread!
      Secondly, you're reimplementing QThread::run() instead of using a worker object and the thread's own event loop.
      Thirdly (a remark), if you want the QTcpSocket object that you get from QTcpServer to live in another thread you have to reimplement QTcpServer::incomingConnection.
      Fourthly, you shouldn't be calling start() in the constructor.
      And finally, you have a race condition:

      void NetworkEvents::run()
      {
          if(server->isListening()) // << Calling a method of an object in one thread
          // ...
      }
      
      NetworkSupport::NetworkSupport(QObject *mainObj):QObject(mainObj)
      {
          server = new QTcpServer(mainObj);
          server->listen(QHostAdress::Any, 5200);  // << Calling, initializing and using an object in another thread
          // ...
      }
      

      Fix all of those, and everything should start to work smoothly.
      Kind regards.

      PS.

      networkLoop = new QEventLoop(mainObj);
      

      This is not freed anywhere, so if you didn't cut the delete only for the example code, then you have a memory leak as well.
      I need sleep, you parented it, so it's just fine.

      PS 2.
      Are you sure there is indeed a pending connection to that port?

      Read and abide by the Qt Code of Conduct

      Q 1 Reply Last reply 23 Mar 2016, 09:49
      1
      • K kshegunov
        23 Mar 2016, 09:42

        @QtExchange
        Hi,
        You're doing it wrong, on multiple counts.

        Firstly, your objects are all in the main thread!
        Secondly, you're reimplementing QThread::run() instead of using a worker object and the thread's own event loop.
        Thirdly (a remark), if you want the QTcpSocket object that you get from QTcpServer to live in another thread you have to reimplement QTcpServer::incomingConnection.
        Fourthly, you shouldn't be calling start() in the constructor.
        And finally, you have a race condition:

        void NetworkEvents::run()
        {
            if(server->isListening()) // << Calling a method of an object in one thread
            // ...
        }
        
        NetworkSupport::NetworkSupport(QObject *mainObj):QObject(mainObj)
        {
            server = new QTcpServer(mainObj);
            server->listen(QHostAdress::Any, 5200);  // << Calling, initializing and using an object in another thread
            // ...
        }
        

        Fix all of those, and everything should start to work smoothly.
        Kind regards.

        PS.

        networkLoop = new QEventLoop(mainObj);
        

        This is not freed anywhere, so if you didn't cut the delete only for the example code, then you have a memory leak as well.
        I need sleep, you parented it, so it's just fine.

        PS 2.
        Are you sure there is indeed a pending connection to that port?

        Q Offline
        Q Offline
        QtExchange
        wrote on 23 Mar 2016, 09:49 last edited by QtExchange
        #3

        @kshegunov thank you very much, I'm already taking out some mistakes. My client program reacts on SIGNAL(connected()), which was only emitted when the server as shown above was running.

        K 1 Reply Last reply 23 Mar 2016, 09:54
        0
        • Q QtExchange
          23 Mar 2016, 09:49

          @kshegunov thank you very much, I'm already taking out some mistakes. My client program reacts on SIGNAL(connected()), which was only emitted when the server as shown above was running.

          K Offline
          K Offline
          kshegunov
          Moderators
          wrote on 23 Mar 2016, 09:54 last edited by kshegunov
          #4

          @QtExchange
          I suggest first testing with a single threaded code. Then, when you're sure it's working fine and all the connections are okay, you can make the worker object and start a new thread, move the worker to that thread and connect the signals. When that's fixed (this means not deriving from QThread and not using a local event loop) you should start to see the slots called responding to the signals emitted from the tcp socket objects.

          Read and abide by the Qt Code of Conduct

          Q 2 Replies Last reply 23 Mar 2016, 10:06
          0
          • K kshegunov
            23 Mar 2016, 09:54

            @QtExchange
            I suggest first testing with a single threaded code. Then, when you're sure it's working fine and all the connections are okay, you can make the worker object and start a new thread, move the worker to that thread and connect the signals. When that's fixed (this means not deriving from QThread and not using a local event loop) you should start to see the slots called responding to the signals emitted from the tcp socket objects.

            Q Offline
            Q Offline
            QtExchange
            wrote on 23 Mar 2016, 10:06 last edited by
            #5

            @kshegunov it was already working in a laboratory situation, these errors only occur since the integration in the main program.

            What exactly do you mean by do not reimplement ::run() (what is the alternative?), if I transfer the code from the run() (as shown above) directly to the constructor (including the exec()) everything runs fine already but then the main program gets stuck on this infinit-exec()-loop too. This is the reason why I implemented the thread/run, but when this is executed in the run() it starts ignoring its signals

            K 1 Reply Last reply 23 Mar 2016, 10:08
            0
            • Q QtExchange
              23 Mar 2016, 10:06

              @kshegunov it was already working in a laboratory situation, these errors only occur since the integration in the main program.

              What exactly do you mean by do not reimplement ::run() (what is the alternative?), if I transfer the code from the run() (as shown above) directly to the constructor (including the exec()) everything runs fine already but then the main program gets stuck on this infinit-exec()-loop too. This is the reason why I implemented the thread/run, but when this is executed in the run() it starts ignoring its signals

              K Offline
              K Offline
              kshegunov
              Moderators
              wrote on 23 Mar 2016, 10:08 last edited by
              #6

              @QtExchange
              Here is some reading material on how to use threads with event loop (which should be in 99.99% of cases), start from top to bottom the first one being the simplest and most relevant:

              https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/
              http://forum.qt.io/topic/64346/qtextdocument-and-multithreading/2
              http://forum.qt.io/topic/63482/qthreads-and-constantly-reusing-the-same-thread-objects/2

              Read and abide by the Qt Code of Conduct

              1 Reply Last reply
              0
              • K kshegunov
                23 Mar 2016, 09:54

                @QtExchange
                I suggest first testing with a single threaded code. Then, when you're sure it's working fine and all the connections are okay, you can make the worker object and start a new thread, move the worker to that thread and connect the signals. When that's fixed (this means not deriving from QThread and not using a local event loop) you should start to see the slots called responding to the signals emitted from the tcp socket objects.

                Q Offline
                Q Offline
                QtExchange
                wrote on 23 Mar 2016, 10:12 last edited by
                #7

                @kshegunov ah should have read longer...

                if I got you right I'm just doing the implementation and the threading in the wrong order, let me check on that

                K 1 Reply Last reply 23 Mar 2016, 10:14
                0
                • Q QtExchange
                  23 Mar 2016, 10:12

                  @kshegunov ah should have read longer...

                  if I got you right I'm just doing the implementation and the threading in the wrong order, let me check on that

                  K Offline
                  K Offline
                  kshegunov
                  Moderators
                  wrote on 23 Mar 2016, 10:14 last edited by
                  #8

                  @QtExchange
                  Forgot to link those two, which are very important to understand before working with threads:
                  QObjects' thread affinity: http://doc.qt.io/qt-5/qobject.html#thread-affinity
                  Queued connections accros threads: http://doc.qt.io/qt-5/threads-qobject.html#signals-and-slots-across-threads

                  Read and abide by the Qt Code of Conduct

                  1 Reply Last reply
                  1

                  1/8

                  23 Mar 2016, 09:14

                  • Login

                  • Login or register to search.
                  1 out of 8
                  • First post
                    1/8
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved