Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Unsolved QTcpServer for manage many clients with blocking operations

    General and Desktop
    3
    7
    227
    Loading More Posts
    • 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.
    • F
      FalsinSoft last edited by

      Hi all

      I'm developing a server tool for manage many clients connected through socket connections. For the server I use QTcpServer and for the clients (developed by me also) QTcpSocketas as obvious. Server need to continuously interact with clients with also some blocking commands waiting for immediately reply than I need to use threads for keep GUI responsive. Using the returned client socket after connection in a separate thread is cleared explained in the documentation by derive incomingConnection() and use the socketdescriptor value. Now the problem. Assign to each client a dedicated thread doesn't seem a good idea cause connected clients can be many. Alternative can be use a thread pool for execute each single task. There are good examples regarding how to use socket in a thread in the Qt documentation and also around in Internet but all example I found, after passed the socketDescriptor to the thread for allow to use the QTcpSocket, close the socket once the operation is finished that is not what I want to do. I need the socket connection will remain open for all the time but in this case how to "move" temporarily the socket to the thread just only for execute the blocking operation?
      Thank you for the help

      KroMignon 1 Reply Last reply Reply Quote 0
      • KroMignon
        KroMignon @FalsinSoft last edited by KroMignon

        @FalsinSoft said in QTcpServer for manage many clients with blocking operations:

        I need the socket connection will remain open for all the time but in this case how to "move" temporarily the socket to the thread just only for execute the blocking operation?

        I would suggest you to use QtConcurrent::run() to run the function in another thread and wait of execution done with help of QEventLoop and QFutureWatcher.

        Something like:

        // suppose return function type is void
        QFutureWatcher<void> watcher;
        QEventLoop loop;
        
        connect(&watcher, &QFutureWatcher<void>::finished, &loop, &QEventLoop::quit);
        connect(&watcher, &QFutureWatcher<void>::canceled, &loop, &QEventLoop::quit);
        QFuture<void> future= QtConcurrent::run(this, &MyClass::longFunctionToRun, parameters);
        watcher.setFuture(future);
        // wait until future is done without locking current thread!!
        qDebug() << "Waiting result";
        loop.exec();
        qDebug() << "Processing done.";
        
        

        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 Reply Quote 0
        • F
          FalsinSoft last edited by

          QtConcurrent::run() basically use a thread pool but the problem remain. Based to the documentation QTcpSocket can not be used to a thread different from the original one where it has been created. I can pas the socketDescriptor and create the QTcpSocket inside the function ran with QtConcurrent::run() but when function will finish the QTcpSocket will be destroyed and the socket closed....

          mrjj KroMignon 2 Replies Last reply Reply Quote 0
          • mrjj
            mrjj Lifetime Qt Champion @FalsinSoft last edited by

            @FalsinSoft
            Hi
            Do you really need to use the blocking api ?
            Using the async API only takes a little bit more code to have a state system to do the next thing after getting a reply.

            F 1 Reply Last reply Reply Quote 0
            • F
              FalsinSoft @mrjj last edited by

              Do you really need to use the blocking api ?

              Yes, there are just a couple of commands but manage them with asynchronous code excessively complicates the whole project

              1 Reply Last reply Reply Quote 0
              • KroMignon
                KroMignon @FalsinSoft last edited by

                @FalsinSoft said in QTcpServer for manage many clients with blocking operations:

                QtConcurrent::run() basically use a thread pool but the problem remain. Based to the documentation QTcpSocket can not be used to a thread different from the original one where it has been created.

                My suggestion was to "export" the long time processing function into another thread, but this does not mean socket read/write.
                When processing is done, you can then send result to TCP client from the right thread.

                But I don't have any idea of your software, maybe this is not applicable.

                Another possibility is to define a QThreadPool depending on the cpu count, and loop through this pool to select a thread to handle new connected client.
                So you would not look main thread. But, as you should know, Qt design is asynchronous, so use it with blocking API is not the best way.

                I would suggest you to rework your application concept to be more "Qt friendly" or perhaps use another C++ library which better fit your needs.

                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 Reply Quote 0
                • F
                  FalsinSoft last edited by

                  I know asynchronous is the better way use Qt but, in my opinion, sometimes is useless to complicate too much the code when a more simply solution of use a blocking operation is available. I'm referring to the Qt function QAbstractSocket::waitForReadyRead() that is available exactly for this purpose (there is also the official example "Blocking Fortune Client Example"). In this thread I just would to know if is possible to use this blocking feature in the way I need. If not possible I'll move to the asynchronous way...

                  1 Reply Last reply Reply Quote 0
                  • First post
                    Last post