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. QThread, QUdpSocket non-blocking

QThread, QUdpSocket non-blocking

Scheduled Pinned Locked Moved Solved General and Desktop
11 Posts 3 Posters 5.8k 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.
  • PuntP Offline
    PuntP Offline
    Punt
    wrote on last edited by
    #1

    Hi guys,
    first, i'll try my best in English, so sorry if there's some mistakes.

    Here is my code :

    class threadCom : public QThread
    {
        Q_OBJECT
    public:
        explicit threadCom(QObject *parent = 0);
        void run();
    private:
        QUdpSocket *m_socketRec;
        void bind();
        QStack<QByteArray> *m_pileIP;
    
    public slots:
        void readPendingDatagrams();
    
    };
    
    
    void threadCom::bind(){
        if(m_socketRec->bind(m_address, m_portRec)){ //m_address & m_portRec are set don't worry :p
            std::cerr << "Connected" << std::endl;
            connect(m_socketRec, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams()));
        }
        else{
            std::cerr << "Fail" << std::endl;
        }
    }
    

    And in my thread,
    i would like to :

    • Wait for a new data in my QStack ( readPendingDatagrams add a QByteArray when there is a new frame in my socket)
    • or wait for a timeout if there is no frame on my QStack

    =>

    run(){
    
        forever{
             QTimer *timer_nb = new QTimer();
             timer_nb->start(500);
    
             // --- Wait for timeout or new frames in my QStack
             //then ....
        }
    }
    

    That's the idea..
    But i'm having trouble with threads (I'm new with this)
    I guess I should use waitForReadyRead( myTimeout ) ?

    I tried 50 different way, none was the good one...

    (Btw, I need to use Threads, because when I ask, a lot of people say I don't need threads to do that, but that's imposed !)

    JKSHJ 1 Reply Last reply
    0
    • PuntP Punt

      Hi guys,
      first, i'll try my best in English, so sorry if there's some mistakes.

      Here is my code :

      class threadCom : public QThread
      {
          Q_OBJECT
      public:
          explicit threadCom(QObject *parent = 0);
          void run();
      private:
          QUdpSocket *m_socketRec;
          void bind();
          QStack<QByteArray> *m_pileIP;
      
      public slots:
          void readPendingDatagrams();
      
      };
      
      
      void threadCom::bind(){
          if(m_socketRec->bind(m_address, m_portRec)){ //m_address & m_portRec are set don't worry :p
              std::cerr << "Connected" << std::endl;
              connect(m_socketRec, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams()));
          }
          else{
              std::cerr << "Fail" << std::endl;
          }
      }
      

      And in my thread,
      i would like to :

      • Wait for a new data in my QStack ( readPendingDatagrams add a QByteArray when there is a new frame in my socket)
      • or wait for a timeout if there is no frame on my QStack

      =>

      run(){
      
          forever{
               QTimer *timer_nb = new QTimer();
               timer_nb->start(500);
      
               // --- Wait for timeout or new frames in my QStack
               //then ....
          }
      }
      

      That's the idea..
      But i'm having trouble with threads (I'm new with this)
      I guess I should use waitForReadyRead( myTimeout ) ?

      I tried 50 different way, none was the good one...

      (Btw, I need to use Threads, because when I ask, a lot of people say I don't need threads to do that, but that's imposed !)

      JKSHJ Offline
      JKSHJ Offline
      JKSH
      Moderators
      wrote on last edited by
      #2

      Hi @Punt, and welcome to the Qt Dev Net!

      forever{
           QTimer *timer_nb = new QTimer();
      

      The forever loop will block the Qt event loop. If you want to use signals and slots, you cannot use forever.

      I tried 50 different way, none was the good one...

      Did you read the QThread documentation? There are some examples there: http://doc.qt.io/qt-5/qthread.html

      (Btw, I need to use Threads, because when I ask, a lot of people say I don't need threads to do that, but that's imposed !)

      Imposed by who? Why do you need to use threads?

      Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

      PuntP 1 Reply Last reply
      0
      • JKSHJ JKSH

        Hi @Punt, and welcome to the Qt Dev Net!

        forever{
             QTimer *timer_nb = new QTimer();
        

        The forever loop will block the Qt event loop. If you want to use signals and slots, you cannot use forever.

        I tried 50 different way, none was the good one...

        Did you read the QThread documentation? There are some examples there: http://doc.qt.io/qt-5/qthread.html

        (Btw, I need to use Threads, because when I ask, a lot of people say I don't need threads to do that, but that's imposed !)

        Imposed by who? Why do you need to use threads?

        PuntP Offline
        PuntP Offline
        Punt
        wrote on last edited by
        #3

        @JKSH said:

        Hi @Punt, and welcome to the Qt Dev Net!

        Thanks !

        The forever loop will block the Qt event loop. If you want to use signals and slots, you cannot use forever.

        y, I don't use anymore forever, I have to use exec() right ?

        Did you read the QThread documentation? There are some examples there: http://doc.qt.io/qt-5/qthread.html

        I did ! But I guess i'm lost with everything I read this morning x)

        (Btw, I need to use Threads, because when I ask, a lot of people say I don't need threads to do that, but that's imposed !)

        Imposed by who? Why do you need to use threads?

        Because I'll have a GUI, and I'll receive data to update my GUI, and I'll have to send data (with the state of my buttons on my GUI) => I'll have 2 threads, one for my UDP connexion, one for my GUI. these threads can be synchronized (When I received a new data, I signal my GUI's thread that he needs to do a loop)

        JKSHJ 1 Reply Last reply
        0
        • jsulmJ Offline
          jsulmJ Offline
          jsulm
          Lifetime Qt Champion
          wrote on last edited by
          #4

          Qt networking is asynchronous so there is usually no need for multi-threading.

          https://forum.qt.io/topic/113070/qt-code-of-conduct

          PuntP 1 Reply Last reply
          0
          • jsulmJ jsulm

            Qt networking is asynchronous so there is usually no need for multi-threading.

            PuntP Offline
            PuntP Offline
            Punt
            wrote on last edited by
            #5
            run() //Of my UDP Thread
            {
                if(m_bloquant) //if blocking UDP connection
                    //wait for a new frame
                else // non-blocking 
                    //wait for a new frame OR a timeout
            
                //then ...
                //share the new frame with GUI's thread
                //(if my 2 threads are synchronized) : emit to my GUI's thread to loop (GUI's thread will share data with UDP's thread)
                //Send data (in another socket udp)
                
                //loop
            
            }
            

            that's what I want to do !

            1 Reply Last reply
            0
            • PuntP Offline
              PuntP Offline
              Punt
              wrote on last edited by
              #6

              Another try :

              void threadCom::run(){ 
                  bind(); // new QUdpSocket() & bind
              
                  if(!m_bloquant){ //if non-blocking
                      m_timer_b = new QTimer(); // QTimer
                      connect(m_timer_b, SIGNAL(timeout()), this, SLOT(startCycle())); // One cycle + reset timer
                      m_timer_b->start(m_timeout_b); 
                  }
                  connect(m_socketRec, SIGNAL(readyRead()), SLOT(readPendingDatagrams())); 
                      exec();
              }
              
              void threadCom::startCycle(){
                  if(!m_pileIP->isEmpty()) // if data in QStack
                  {
                      m_dataShared->setData(m_pileIP->pop());  //share data
                      m_pileIP->clear();
                  }
                  if(m_sync) //if SYNC with GUI's thread
                      emit needTraitement(); 
                  sendDatagrams(); //Just a cout but soon QUdpSocket_sender.write(something)
                  if(!m_bloquant) // if non-blocking
                      m_timer_b->start(m_timeout_b);  //reset timeout
              }
              

              and in ReadPendingDatagrams, I added a reset timeout too.

              But this is looping just one time and doing nothing more ...

              1 Reply Last reply
              0
              • PuntP Punt

                @JKSH said:

                Hi @Punt, and welcome to the Qt Dev Net!

                Thanks !

                The forever loop will block the Qt event loop. If you want to use signals and slots, you cannot use forever.

                y, I don't use anymore forever, I have to use exec() right ?

                Did you read the QThread documentation? There are some examples there: http://doc.qt.io/qt-5/qthread.html

                I did ! But I guess i'm lost with everything I read this morning x)

                (Btw, I need to use Threads, because when I ask, a lot of people say I don't need threads to do that, but that's imposed !)

                Imposed by who? Why do you need to use threads?

                Because I'll have a GUI, and I'll receive data to update my GUI, and I'll have to send data (with the state of my buttons on my GUI) => I'll have 2 threads, one for my UDP connexion, one for my GUI. these threads can be synchronized (When I received a new data, I signal my GUI's thread that he needs to do a loop)

                JKSHJ Offline
                JKSHJ Offline
                JKSH
                Moderators
                wrote on last edited by
                #7

                @Punt said:

                y, I don't use anymore forever, I have to use exec() right ?

                Right. If you want to use signals and slots, you must use exec(), not forever.

                I did ! But I guess i'm lost with everything I read this morning x)

                Threads can be tricky. I recommend that you don't use threads, unless you really really have to.

                Because I'll have a GUI, and I'll receive data to update my GUI, and I'll have to send data (with the state of my buttons on my GUI) => I'll have 2 threads, one for my UDP connexion, one for my GUI. these threads can be synchronized (When I received a new data, I signal my GUI's thread that he needs to do a loop)

                Well, like @jsulm said, Qt has the power to let you send/receive UDP data AND update the GUI using only one thread :)

                See these simple examples:

                • http://doc.qt.io/qt-5/qtnetwork-multicastreceiver-example.html
                • http://doc.qt.io/qt-5/qtnetwork-multicastsender-example.html

                (Or, in Qt Creator, search for the "Broadcast Sender" and "Broadcast Receiver" examples)

                Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                PuntP 1 Reply Last reply
                0
                • JKSHJ JKSH

                  @Punt said:

                  y, I don't use anymore forever, I have to use exec() right ?

                  Right. If you want to use signals and slots, you must use exec(), not forever.

                  I did ! But I guess i'm lost with everything I read this morning x)

                  Threads can be tricky. I recommend that you don't use threads, unless you really really have to.

                  Because I'll have a GUI, and I'll receive data to update my GUI, and I'll have to send data (with the state of my buttons on my GUI) => I'll have 2 threads, one for my UDP connexion, one for my GUI. these threads can be synchronized (When I received a new data, I signal my GUI's thread that he needs to do a loop)

                  Well, like @jsulm said, Qt has the power to let you send/receive UDP data AND update the GUI using only one thread :)

                  See these simple examples:

                  • http://doc.qt.io/qt-5/qtnetwork-multicastreceiver-example.html
                  • http://doc.qt.io/qt-5/qtnetwork-multicastsender-example.html

                  (Or, in Qt Creator, search for the "Broadcast Sender" and "Broadcast Receiver" examples)

                  PuntP Offline
                  PuntP Offline
                  Punt
                  wrote on last edited by Punt
                  #8

                  @JKSH

                  Ok, I'm not using anymore QThreads for my UDP connection,
                  but now I need a class with a QThread which works like that :

                  run(){
                      if( myapp.isSync() )
                          //wait for a signal from my UDP class
                      
                      ...
                      //treatment
                      ...    
                      
                      
                      if( ! myapp.isSync() )
                          msleep( timeout );
                  }
                  

                  Which mean, if my UDP class & this threads are synchronized, I wait a signal from my UDP class to start a loop (and then wait for another signal, etc..... = exec() ?)
                  How do I do that ?

                  JKSHJ 1 Reply Last reply
                  0
                  • PuntP Punt

                    @JKSH

                    Ok, I'm not using anymore QThreads for my UDP connection,
                    but now I need a class with a QThread which works like that :

                    run(){
                        if( myapp.isSync() )
                            //wait for a signal from my UDP class
                        
                        ...
                        //treatment
                        ...    
                        
                        
                        if( ! myapp.isSync() )
                            msleep( timeout );
                    }
                    

                    Which mean, if my UDP class & this threads are synchronized, I wait a signal from my UDP class to start a loop (and then wait for another signal, etc..... = exec() ?)
                    How do I do that ?

                    JKSHJ Offline
                    JKSHJ Offline
                    JKSH
                    Moderators
                    wrote on last edited by
                    #9

                    @Punt said:

                    if my UDP class & this threads are synchronized

                    Can you describe how you planned to synchronize your threads?

                    run(){
                        if( myapp.isSync() )
                            //wait for a signal from my UDP class
                        
                        ...
                        //treatment
                        ...    
                        
                        
                        if( ! myapp.isSync() )
                            msleep( timeout );
                    }
                    

                    You just need to use event-driven programming.

                    class UdpSignalHandler : public QObject
                    {
                        Q_OBJECT
                    
                        //...
                    
                    public slots:
                         void doTreatment {
                            //treatment
                        }
                    };
                    
                    int main(int argc, char **argv) {
                    
                        QApplication app(argc, argv);
                    
                        // ...
                    
                        auto handler = new UdpSignalHandler;
                    
                        QObject::connect(udpSocket, &QUdpSocket::readyRead,
                                handler, &UdpSignalHandler::doTreatment);
                    
                        /*--------------------------*/
                        /* This part is optional!   */
                        auto thread = new QThread;
                        handler->moveToThread(thread);
                        thread->start();
                        /*--------------------------*/
                    
                        // ...
                    
                        app.exec();
                    }
                    

                    That's it. Now, every time the UDP socket emits a signal, your UdpSignalHandler will run the doTreatment() function in the other thread. Also, you don't need to ask your thread to sleep. It will automatically sleep when there are no signals.

                    Finally, I still don't think you need threads. if you delete the code that I marked "optional", your program will still run -- all in the main thread.

                    (Note: My code doesn't include deleting the objects. You must handle this yourself)

                    Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                    PuntP 1 Reply Last reply
                    0
                    • JKSHJ JKSH

                      @Punt said:

                      if my UDP class & this threads are synchronized

                      Can you describe how you planned to synchronize your threads?

                      run(){
                          if( myapp.isSync() )
                              //wait for a signal from my UDP class
                          
                          ...
                          //treatment
                          ...    
                          
                          
                          if( ! myapp.isSync() )
                              msleep( timeout );
                      }
                      

                      You just need to use event-driven programming.

                      class UdpSignalHandler : public QObject
                      {
                          Q_OBJECT
                      
                          //...
                      
                      public slots:
                           void doTreatment {
                              //treatment
                          }
                      };
                      
                      int main(int argc, char **argv) {
                      
                          QApplication app(argc, argv);
                      
                          // ...
                      
                          auto handler = new UdpSignalHandler;
                      
                          QObject::connect(udpSocket, &QUdpSocket::readyRead,
                                  handler, &UdpSignalHandler::doTreatment);
                      
                          /*--------------------------*/
                          /* This part is optional!   */
                          auto thread = new QThread;
                          handler->moveToThread(thread);
                          thread->start();
                          /*--------------------------*/
                      
                          // ...
                      
                          app.exec();
                      }
                      

                      That's it. Now, every time the UDP socket emits a signal, your UdpSignalHandler will run the doTreatment() function in the other thread. Also, you don't need to ask your thread to sleep. It will automatically sleep when there are no signals.

                      Finally, I still don't think you need threads. if you delete the code that I marked "optional", your program will still run -- all in the main thread.

                      (Note: My code doesn't include deleting the objects. You must handle this yourself)

                      PuntP Offline
                      PuntP Offline
                      Punt
                      wrote on last edited by Punt
                      #10

                      @JKSH
                      I need a thread because this thread can work "not synchronized" with my UDP class.

                      Here, when I receive a signal, I'll have to check if there is new datas shared by both class, if so treat them. Then my UdpSignalHandler will update my GUI, share other datas(the state of GUI's button for example) with my UDP class,

                      But if this is not-synchronized, my UdpSignalHandler will have to do all of that, all the time with a little sleep().²

                      JKSHJ 1 Reply Last reply
                      0
                      • PuntP Punt

                        @JKSH
                        I need a thread because this thread can work "not synchronized" with my UDP class.

                        Here, when I receive a signal, I'll have to check if there is new datas shared by both class, if so treat them. Then my UdpSignalHandler will update my GUI, share other datas(the state of GUI's button for example) with my UDP class,

                        But if this is not-synchronized, my UdpSignalHandler will have to do all of that, all the time with a little sleep().²

                        JKSHJ Offline
                        JKSHJ Offline
                        JKSH
                        Moderators
                        wrote on last edited by JKSH
                        #11

                        @Punt said:

                        I need a thread because this thread can work "not synchronized" with my UDP class.

                        Sorry, I don't quite understand. Can you give an example of:

                        1. When the two are "synchronized"?
                        2. When the two are "not synchronized"?

                        Here, when I receive a signal, I'll have to check if there is new datas shared by both class, if so treat them.

                        The QUdpSocket will only emit the signal when there is new data, right?

                        If there is no new data, then UdpSignalHandler::doTreatment() will not run.

                        Then my UdpSignalHandler will update my GUI, share other datas(the state of GUI's button for example) with my UDP class

                        Note: If your UdpSignalHandler lives in another thread, then it is not allowed to read/write the GUI directly. For example, you must not call QLabel::setText() from another thread; you must only call it from the main thread.

                        If the UdpSignalHandler wants to update the GUI, it must emit a signal. Then, let a GUI object's slot update the GUI.

                        Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                        1 Reply Last reply
                        0

                        • Login

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