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. Minimal example of proper way of forever-running server like QUdpSocket

Minimal example of proper way of forever-running server like QUdpSocket

Scheduled Pinned Locked Moved Unsolved General and Desktop
qfutureqtconcurrent
16 Posts 6 Posters 1.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.
  • mrjjM Offline
    mrjjM Offline
    mrjj
    Lifetime Qt Champion
    wrote on last edited by
    #3

    Hi and welcome to the forums.

    Qt's network classes are asynchronous pr default meaning that unless you want to do really heavy stuff there is no reason to use a thread at all since the app won't be blocked.

    But do you mean how to make such an app in general?

    Like for your own server type?

    Anyway, say your server does need a thread.
    then look at here for various ways.

    https://github.com/DeiVadder/QtThreadExample

    Im a fan of the worker way as it allows reuse of the core object in easy manner.

    P 1 Reply Last reply
    3
    • Christian EhrlicherC Christian Ehrlicher

      Then don't use QtConurrent::run() but a proper QThread which is more suitable for your purpose. Also I don't see why a QUdServer needs to be in a separate thread at all.

      P Offline
      P Offline
      perry_blueberry
      wrote on last edited by
      #4

      @Christian-Ehrlicher
      I might have worded it the wrong way but I'm not trying to put QUdpSocket in a thread, I'm trying to do what QUdpSocket is doing and just use connect on my own server and have it emit a signal whenever new data is available. If that is in a thread or not doesn't really matter; I just want it to work the same as that one.

      Do you know of any examples I could look at?

      1 Reply Last reply
      0
      • Christian EhrlicherC Offline
        Christian EhrlicherC Offline
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote on last edited by
        #5

        @perry_blueberry said in Minimal example of proper way of forever-running server like QUdpSocket:

        Do you know of any examples I could look at?

        In the documentation are exactly the 5 lines you need for this.

        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
        Visit the Qt Academy at https://academy.qt.io/catalog

        1 Reply Last reply
        0
        • mrjjM mrjj

          Hi and welcome to the forums.

          Qt's network classes are asynchronous pr default meaning that unless you want to do really heavy stuff there is no reason to use a thread at all since the app won't be blocked.

          But do you mean how to make such an app in general?

          Like for your own server type?

          Anyway, say your server does need a thread.
          then look at here for various ways.

          https://github.com/DeiVadder/QtThreadExample

          Im a fan of the worker way as it allows reuse of the core object in easy manner.

          P Offline
          P Offline
          perry_blueberry
          wrote on last edited by
          #6

          @mrjj said in Minimal example of proper way of forever-running server like QUdpSocket:

          Hi and welcome to the forums.

          Qt's network classes are asynchronous pr default meaning that unless you want to do really heavy stuff there is no reason to use a thread at all since the app won't be blocked.

          But do you mean how to make such an app in general?

          Like for your own server type?

          Anyway, say your server does need a thread.
          then look at here for various ways.

          https://github.com/DeiVadder/QtThreadExample

          Im a fan of the worker way as it allows reuse of the core object in easy manner.

          The redmarked is exactly what I want. The example linked seems to be for doing some heavy operation. That example seems to pop up a lot but I think doing a server is fundamentally different (maybe not in Qt?). Probably stating the obvious, put a server is IO bound and runs forever whereas a heavy task is CPU bound and runs to completion. I think the best way to create a server is generally through some sort of asynchronous calls like QUdpSocket looks to me from the outside looking in.

          @Christian-Ehrlicher said in Minimal example of proper way of forever-running server like QUdpSocket:

          @perry_blueberry said in Minimal example of proper way of forever-running server like QUdpSocket:

          Do you know of any examples I could look at?

          In the documentation are exactly the 5 lines you need for this.

          I am not trying to implement a UDP server. I am trying to implement my own (CAN). Through continually polling for messages I can get new messages with the library I'm using so for that to work it would need to run in some sort of therad. What that documentation shows is what I want the API for my own server to look like.

          1 Reply Last reply
          0
          • Christian EhrlicherC Offline
            Christian EhrlicherC Offline
            Christian Ehrlicher
            Lifetime Qt Champion
            wrote on last edited by
            #7

            @perry_blueberry said in Minimal example of proper way of forever-running server like QUdpSocket:

            I am not trying to implement a UDP server. I am trying to implement my own (CAN). Through continually polling for messages I can get new messages with the library I'm using so for that to work it would need to run in some sort of therad. What that documentation shows is what I want the API for my own server to look like.

            So what's wrong with my first comment then? Use a separate QThread and properly close it on exit instead QtConcurrent::run() which is not designed for this usecase.

            Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
            Visit the Qt Academy at https://academy.qt.io/catalog

            P 1 Reply Last reply
            0
            • Christian EhrlicherC Christian Ehrlicher

              @perry_blueberry said in Minimal example of proper way of forever-running server like QUdpSocket:

              I am not trying to implement a UDP server. I am trying to implement my own (CAN). Through continually polling for messages I can get new messages with the library I'm using so for that to work it would need to run in some sort of therad. What that documentation shows is what I want the API for my own server to look like.

              So what's wrong with my first comment then? Use a separate QThread and properly close it on exit instead QtConcurrent::run() which is not designed for this usecase.

              P Offline
              P Offline
              perry_blueberry
              wrote on last edited by
              #8

              @Christian-Ehrlicher
              I have looked at the examples. From the second example I have this

              //mainwindow.cpp
              #include "mainwindow.h"
              #include "ui_mainwindow.h"
              #include "WorkerThread.h"
              #include <QDebug>
              
              MainWindow::MainWindow(QWidget *parent)
                  : QMainWindow(parent)
                  , ui(new Ui::MainWindow)
              {
                  ui->setupUi(this);
              
                  WorkerThread *workerThread = new WorkerThread();
                  connect(workerThread, &WorkerThread::resultReady, this, &MainWindow::handleResult);
                  connect(workerThread, &WorkerThread::finished, workerThread, &QObject::deleteLater);
                  workerThread->start();
              }
              
              MainWindow::~MainWindow()
              {
                  delete ui;
              }
              
              void MainWindow::handleResult(const QString &s)
              {
                  qDebug() << "Got results";
              }
              
              //WorkerThread.h
              #ifndef WORKERTHREAD_H
              #define WORKERTHREAD_H
              #include <QThread>
              class WorkerThread : public QThread
              {
                  Q_OBJECT
                  void run() override {
                      QString result;
                      /* ... here is the expensive or blocking operation ... */
                      emit resultReady(result);
                      this->exec();
                  }
              signals:
                  void resultReady(const QString &s);
              };
              #endif // WORKERTHREAD_H
              
              

              From this I see Got results one time. The documentation states that using exec() inside run I should be able to event loop this and get it to run many times but that doesn't work. I guess I'm doing something fundamentally wrong here? Putting while(true) causes the same issue as before where the program cannot exit without a crash.

              KroMignonK 1 Reply Last reply
              0
              • P perry_blueberry

                @Christian-Ehrlicher
                I have looked at the examples. From the second example I have this

                //mainwindow.cpp
                #include "mainwindow.h"
                #include "ui_mainwindow.h"
                #include "WorkerThread.h"
                #include <QDebug>
                
                MainWindow::MainWindow(QWidget *parent)
                    : QMainWindow(parent)
                    , ui(new Ui::MainWindow)
                {
                    ui->setupUi(this);
                
                    WorkerThread *workerThread = new WorkerThread();
                    connect(workerThread, &WorkerThread::resultReady, this, &MainWindow::handleResult);
                    connect(workerThread, &WorkerThread::finished, workerThread, &QObject::deleteLater);
                    workerThread->start();
                }
                
                MainWindow::~MainWindow()
                {
                    delete ui;
                }
                
                void MainWindow::handleResult(const QString &s)
                {
                    qDebug() << "Got results";
                }
                
                //WorkerThread.h
                #ifndef WORKERTHREAD_H
                #define WORKERTHREAD_H
                #include <QThread>
                class WorkerThread : public QThread
                {
                    Q_OBJECT
                    void run() override {
                        QString result;
                        /* ... here is the expensive or blocking operation ... */
                        emit resultReady(result);
                        this->exec();
                    }
                signals:
                    void resultReady(const QString &s);
                };
                #endif // WORKERTHREAD_H
                
                

                From this I see Got results one time. The documentation states that using exec() inside run I should be able to event loop this and get it to run many times but that doesn't work. I guess I'm doing something fundamentally wrong here? Putting while(true) causes the same issue as before where the program cannot exit without a crash.

                KroMignonK Offline
                KroMignonK Offline
                KroMignon
                wrote on last edited by KroMignon
                #9

                @perry_blueberry said in Minimal example of proper way of forever-running server like QUdpSocket:

                From this I see Got results one time. The documentation states that using exec() inside run I should be able to event loop this and get it to run many times but that doesn't work. I guess I'm doing something fundamentally wrong here? Putting while(true) causes the same issue as before where the program cannot exit without a crash.

                I don't want to hurt you, but your QThread usage can not work as it is.
                You should never sub-class QThread, especially if you want to use it in combination with QObject:

                • https://doc.qt.io/qt-5/qthread.html#details : "new slots should not be implemented directly into a subclassed QThread."
                • https://www.vikingsoftware.com/how-to-use-qthread-properly/

                I don't really understand what you want to achieve, so I can only guess.
                Correct me if I am wrong.

                My understanding, is that you want to perform a "heavy computing" outside the main thread.
                For this kind of purpose, I would recommend you to use QtConcurrent::run() => https://doc.qt.io/qt-5/qtconcurrentrun.html

                It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                P 1 Reply Last reply
                0
                • KroMignonK KroMignon

                  @perry_blueberry said in Minimal example of proper way of forever-running server like QUdpSocket:

                  From this I see Got results one time. The documentation states that using exec() inside run I should be able to event loop this and get it to run many times but that doesn't work. I guess I'm doing something fundamentally wrong here? Putting while(true) causes the same issue as before where the program cannot exit without a crash.

                  I don't want to hurt you, but your QThread usage can not work as it is.
                  You should never sub-class QThread, especially if you want to use it in combination with QObject:

                  • https://doc.qt.io/qt-5/qthread.html#details : "new slots should not be implemented directly into a subclassed QThread."
                  • https://www.vikingsoftware.com/how-to-use-qthread-properly/

                  I don't really understand what you want to achieve, so I can only guess.
                  Correct me if I am wrong.

                  My understanding, is that you want to perform a "heavy computing" outside the main thread.
                  For this kind of purpose, I would recommend you to use QtConcurrent::run() => https://doc.qt.io/qt-5/qtconcurrentrun.html

                  P Offline
                  P Offline
                  perry_blueberry
                  wrote on last edited by
                  #10

                  @KroMignon
                  No worries, I am here to learn :)
                  But I have to say this keeps on getting more confusing. The example I posted above is taken almost exactly line-by-line from the second example in the Qt documentation that you linked. I have only taken the controller part of it and put it in mainwindow. And it says In that example, the thread will exit after the run function has returned. There will not be any event loop running in the thread unless you call exec(). which makes it seem like you can have this kind of server by calling exec in run (putting it in run is mentioned somewhere close in the documentation).

                  What I want to achieve is an asynchronous server that emits a signal when something is ready to be read. This is a very common way to implement some kind of server in many languages and frameworks that I've seen. A server doesn't run to conclusion and only gives results intermittently so it has to be allowed to run forever somehow while producing new results when they arrive.

                  1 Reply Last reply
                  0
                  • P Offline
                    P Offline
                    perry_blueberry
                    wrote on last edited by
                    #11

                    To avoid confusion, when I say server I want to mention that I don't mean a web server or UDP server. I simply mean something that is blocking on some sort of connection to listen for some data. When that data comes it should make the data available for the rest of the application and then go to sleep again until there is something new to read.

                    KroMignonK 1 Reply Last reply
                    0
                    • nageshN Offline
                      nageshN Offline
                      nagesh
                      wrote on last edited by nagesh
                      #12

                      @perry_blueberry I suggest for your requirement implement ion like this is most suited rather than subclassing thread..
                      connect required slot to socket ready read signal and
                      In the slot read the data and emit the read data.

                      Implement the above functionality in the class..
                      Call it as Worker class. And move this class instance to thread using movetoThread()

                      https://doc.qt.io/qt-5/qthread.html
                      Use the first example in the link which suggests using moveToThread()

                      P 1 Reply Last reply
                      0
                      • P perry_blueberry

                        To avoid confusion, when I say server I want to mention that I don't mean a web server or UDP server. I simply mean something that is blocking on some sort of connection to listen for some data. When that data comes it should make the data available for the rest of the application and then go to sleep again until there is something new to read.

                        KroMignonK Offline
                        KroMignonK Offline
                        KroMignon
                        wrote on last edited by KroMignon
                        #13

                        @perry_blueberry said in Minimal example of proper way of forever-running server like QUdpSocket:

                        When that data comes it should make the data available for the rest of the application and then go to sleep again until there is something new to read.

                        The Qt documentation is very huge, and some examples are out-dated.

                        Qt is an asynchronous framework, almost all Qt class handle this for you.
                        For example:

                        • QTcpSocket / QTcpServer
                        • QUdpSocket
                        • QSerialPort
                        • etc.

                        All those classes handle the "blocking logic" in background and triggers signals "when something happens".
                        For example for QTcpSocket there are connected(), disconnected(), bytesWritten(), readyRead(), etc.

                        So there is no need to use additional thread for this.

                        Again, depending on what you want to do there are many strategies you can use for doing things outside from main thread:

                        • for single operations, the simplest way is to use QtConcurrent::run() (maybe in combination with QFutureWatcher()
                        • or using a "worker class", and using moveToThread() to run it in a background thread

                        It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                        1 Reply Last reply
                        2
                        • nageshN nagesh

                          @perry_blueberry I suggest for your requirement implement ion like this is most suited rather than subclassing thread..
                          connect required slot to socket ready read signal and
                          In the slot read the data and emit the read data.

                          Implement the above functionality in the class..
                          Call it as Worker class. And move this class instance to thread using movetoThread()

                          https://doc.qt.io/qt-5/qthread.html
                          Use the first example in the link which suggests using moveToThread()

                          P Offline
                          P Offline
                          perry_blueberry
                          wrote on last edited by
                          #14

                          @nagesh said in Minimal example of proper way of forever-running server like QUdpSocket:

                          @perry_blueberry I suggest for your requirement implement ion like this is most suited rather than subclassing thread..
                          connect required slot to socket ready read signal and
                          In the slot read the data and emit the read data.

                          Implement the above functionality in the class..
                          Call it as Worker class. And move this class instance to thread using movetoThread()

                          https://doc.qt.io/qt-5/qthread.html
                          Use the first example in the link which suggests using moveToThread()

                          I think I understand what you are saying; subclassing should be avoided for QThread. I will take a look at the links posted in this thread to get a better understanding of the intricacies.

                          @KroMignon said in Minimal example of proper way of forever-running server like QUdpSocket:

                          @perry_blueberry said in Minimal example of proper way of forever-running server like QUdpSocket:

                          When that data comes it should make the data available for the rest of the application and then go to sleep again until there is something new to read.

                          The Qt documentation is very huge, and some examples are out-dated.

                          Qt is an asynchronous framework, almost all Qt class handle this for you.
                          For example:

                          • QTcpSocket / QTcpServer
                          • QUdpSocket
                          • QSerialPort
                          • etc.

                          All those classes handle the "blocking logic" in background and triggers signals "when something happens".
                          For example for QTcpSocket there are connected(), disconnected(), bytesWritten(), readyRead(), etc.

                          So there is no need to use additional thread for this.

                          Again, depending on what you want to do there are many strategies you can use for doing things outside from main thread:

                          • for single operations, the simplest way is to use QtConcurrent::run() (maybe in combination with QFutureWatcher()
                          • or using a "worker class", and using moveToThread() to run it in a background thread

                          My case worked better as a QThread because it is very similar QTcpSocket and the other classes you listed. It was actually shutting down properly in the example I posted above. The issue was that I hadn't put any sleep in between the calls to qDebug so it quickly overtook the CPU. So everything seems to work as expected.

                          To sum up:
                          My first misunderstanding was that I was trying to use QtConcurrent::run which is apparently best suited for single operations. QThread seems to be the right use for a server.
                          I also misunderstood the meaning of exec. I thought it was a "magic" operator that would call run recursively (or something like that) when put at the end of run but it seems to have the purpose of starting the event loop which in turn means starting run. In the end what this boils down to is that I hadn't read the API properly and thinks work more-or-less as expected when comparing to other frameworks.

                          I haven't read it yet but https://www.toptal.com/qt/qt-multithreading-c-plus-plus seems like a good additional resource on the topic (for other people who might be stumbling onto the same issue).

                          kshegunovK 1 Reply Last reply
                          0
                          • P perry_blueberry

                            @nagesh said in Minimal example of proper way of forever-running server like QUdpSocket:

                            @perry_blueberry I suggest for your requirement implement ion like this is most suited rather than subclassing thread..
                            connect required slot to socket ready read signal and
                            In the slot read the data and emit the read data.

                            Implement the above functionality in the class..
                            Call it as Worker class. And move this class instance to thread using movetoThread()

                            https://doc.qt.io/qt-5/qthread.html
                            Use the first example in the link which suggests using moveToThread()

                            I think I understand what you are saying; subclassing should be avoided for QThread. I will take a look at the links posted in this thread to get a better understanding of the intricacies.

                            @KroMignon said in Minimal example of proper way of forever-running server like QUdpSocket:

                            @perry_blueberry said in Minimal example of proper way of forever-running server like QUdpSocket:

                            When that data comes it should make the data available for the rest of the application and then go to sleep again until there is something new to read.

                            The Qt documentation is very huge, and some examples are out-dated.

                            Qt is an asynchronous framework, almost all Qt class handle this for you.
                            For example:

                            • QTcpSocket / QTcpServer
                            • QUdpSocket
                            • QSerialPort
                            • etc.

                            All those classes handle the "blocking logic" in background and triggers signals "when something happens".
                            For example for QTcpSocket there are connected(), disconnected(), bytesWritten(), readyRead(), etc.

                            So there is no need to use additional thread for this.

                            Again, depending on what you want to do there are many strategies you can use for doing things outside from main thread:

                            • for single operations, the simplest way is to use QtConcurrent::run() (maybe in combination with QFutureWatcher()
                            • or using a "worker class", and using moveToThread() to run it in a background thread

                            My case worked better as a QThread because it is very similar QTcpSocket and the other classes you listed. It was actually shutting down properly in the example I posted above. The issue was that I hadn't put any sleep in between the calls to qDebug so it quickly overtook the CPU. So everything seems to work as expected.

                            To sum up:
                            My first misunderstanding was that I was trying to use QtConcurrent::run which is apparently best suited for single operations. QThread seems to be the right use for a server.
                            I also misunderstood the meaning of exec. I thought it was a "magic" operator that would call run recursively (or something like that) when put at the end of run but it seems to have the purpose of starting the event loop which in turn means starting run. In the end what this boils down to is that I hadn't read the API properly and thinks work more-or-less as expected when comparing to other frameworks.

                            I haven't read it yet but https://www.toptal.com/qt/qt-multithreading-c-plus-plus seems like a good additional resource on the topic (for other people who might be stumbling onto the same issue).

                            kshegunovK Offline
                            kshegunovK Offline
                            kshegunov
                            Moderators
                            wrote on last edited by kshegunov
                            #15

                            You have it all here: https://wiki.qt.io/WIP-How_to_create_a_simple_chat_application - single thread, multiple threads, server, client, the works. Courtesy of @VRonin. What you need to do to write this properly is very simple and has nothing to do with threads: you need to make your processing asynchronous. After that it can be in a thread, or not, it doesn't truly matter.

                            Read and abide by the Qt Code of Conduct

                            P 1 Reply Last reply
                            4
                            • kshegunovK kshegunov

                              You have it all here: https://wiki.qt.io/WIP-How_to_create_a_simple_chat_application - single thread, multiple threads, server, client, the works. Courtesy of @VRonin. What you need to do to write this properly is very simple and has nothing to do with threads: you need to make your processing asynchronous. After that it can be in a thread, or not, it doesn't truly matter.

                              P Offline
                              P Offline
                              perry_blueberry
                              wrote on last edited by
                              #16

                              @kshegunov
                              That seems like a great resource! I will take a look.

                              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