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. What is the best approach to handle QTcpSocket (client connection) in a QThread ?
QtWS25 Last Chance

What is the best approach to handle QTcpSocket (client connection) in a QThread ?

Scheduled Pinned Locked Moved Unsolved General and Desktop
7 Posts 3 Posters 2.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.
  • S Offline
    S Offline
    simozz
    wrote on last edited by
    #1

    Hello,

    I am developing a GUI application wich needs to handle many client connections.
    I have to send queries and read replies.

    The main GUI (a subclass of QMainWindow) instantiate many widgets where each one represents a client connection widget and I have to execute a thread for each client connection.

    My doubt is how to handle client connection usin QThread and what is the best approach to this problem.

    I tried to create a subclass of QThread implementing a QTcpSocket (with slots connected to to connected(), disconnected() and readyRead() signals), and overriding the run() of QThread class.
    To show an example of this description, I post a code snippet:

    class ClientWorker : public QThread
    {
        public:
        
        ClientWorker(void);
        ~ClientWorker(void);
    
        void run() override;
        
        qint32 writeData(QByteArray);
        
        public 
            
            slots:
            void socketConnectedSlot(void);
            void socketDisconnectedSlot(void);
            QByteArray readData(void);
        
        private:
            
            // example address and port
            QString address = "192.168.10.10";
            const qint32 port = 5000;
            
            bool loop;
            QTcpSocket *socket;
    
            bool socketConnect(void);
            void socketClose(void);
    };
    
    ClientWorker::ClientWorker(void)
    {
        socket = new QTcpSocket;
        connect(socket, SIGNAL(connected()), this, SLOT(socketConnectedSlot()));
        connect(socket, SIGNAL(disconnected()), this, SLOT(socketDisconnectedSlot()));
        connect(socket, SIGNAL(readyRead()),this, SLOT(readData()));
    
        socketConnect();
    }
    
    bool ClientWorker::socketConnect(void)
    {   
        qDebug() << "Address " << address << ":" << port << endl;
        socket->connectToHost(address, port);
        return socket->waitForConnected();
    }
    
    void ClientWorker::socketClose(void)
    {   
        socket->close();
    }
    
    void ClientWorker::run(void)
    {   
        while(loop)
        {
            qDebug() << "Writing " << cmd << " to " << address;
    
            // example, send data to server socket
            writeData(cmd);
            this->sleep(1);
        }
    }
    
    void ClientWorker::stop(void)
    {
        qDebug() << "Stopped";
        loop = false;
    
        if(socket->state() == QAbstractSocket::ConnectedState)
            socket->close();
    }
    
    void ClientWorker::socketConnectedSlot()
    {
        qDebug() << "Connected to " << address << ":" << port << endl;
        loop = true;
        this->start();
    }
    
    void ClientWorker::socketDisconnectedSlot()
    {
        qDebug() << "Diconnected";
        stop();
    }
    
    QByteArray ClientWorker::readData(void)
    {   
        // read chunk of data
        QByteArray tmpData = socket->readAll();
        qDebug() << "Read " << tmpData.data() << " from " << address;
    
        return tmpData;
    }
    
    qint32 ClientWorker::writeData(QByteArray data)
    {
        qint32 nwrite = 0;
        
        if(socket->state() == QAbstractSocket::ConnectedState)
        {
            qDebug() << data;
            nwrite = socket->write(data);
            socket->waitForBytesWritten();
        }
            
        return nwrite;
    }
    
    

    I understand that this is not the correct way to handle a threaded connection since it doesn't work very well because the socket signals are not handled correctly.

    So what is the best way to handle client threaded connections using a thread running its own loop while handling socket signals ?
    Could you suggest the best approach to this problem ?

    Thanks

    1 Reply Last reply
    0
    • VRoninV Offline
      VRoninV Offline
      VRonin
      wrote on last edited by
      #2

      A few of us here on the forum are working on a good example to illustrate this, it's still a work in progress but the example is already 100% functional, we just need to simplify it and write the step-by-step.

      You can reach it here https://github.com/VSRonin/ChatExample

      Hopefully in a few weeks the example will be complete.

      P.S.
      You don't really need QThread unless the server must do some intensive operation for each client

      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
      ~Napoleon Bonaparte

      On a crusade to banish setIndexWidget() from the holy land of Qt

      1 Reply Last reply
      4
      • S Offline
        S Offline
        simozz
        wrote on last edited by simozz
        #3

        Hello @VRonin,

        Thank you for your example.

        You don't really need QThread unless the server must do some intensive operation for each client

        I would like to know more about this, because right now I feel like I don't have a clear idea.

        The application is multi-client, I mean that each client connects to a different server, and every 1 or 2 s must send a query and receive the respective reply.
        Of course I must be able to connect or disconnect manually each client from the main GUI, so I cannot freeze it.

        As I understand, without a thread the GUI would freeze, and I don't know how to keep the client sending data in a non threaded loop without freezing the GUI.

        EDIT: perhaps I need to redesign the application, as I see from your ChatServer and ServerWorker classes.

        Thanks

        VRoninV 1 Reply Last reply
        0
        • S simozz

          Hello @VRonin,

          Thank you for your example.

          You don't really need QThread unless the server must do some intensive operation for each client

          I would like to know more about this, because right now I feel like I don't have a clear idea.

          The application is multi-client, I mean that each client connects to a different server, and every 1 or 2 s must send a query and receive the respective reply.
          Of course I must be able to connect or disconnect manually each client from the main GUI, so I cannot freeze it.

          As I understand, without a thread the GUI would freeze, and I don't know how to keep the client sending data in a non threaded loop without freezing the GUI.

          EDIT: perhaps I need to redesign the application, as I see from your ChatServer and ServerWorker classes.

          Thanks

          VRoninV Offline
          VRoninV Offline
          VRonin
          wrote on last edited by VRonin
          #4

          The application is multi-client, I mean that each client connects to a different server

          ??? so you mean it is multi-server?

          As I understand, without a thread the GUI would freeze

          Common misunderstanding.

          I would like to know more about this

          Check the QtSimpleChatServer folder it manages multiple clients without blocking. Of course in that example it's just a console application but you are free to change it into a widget application with no changes to the core of the code

          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
          ~Napoleon Bonaparte

          On a crusade to banish setIndexWidget() from the holy land of Qt

          1 Reply Last reply
          0
          • S Offline
            S Offline
            simozz
            wrote on last edited by simozz
            #5

            @VRonin said in What is the best approach to handle QTcpSocket (client connection) in a QThread ?:

            ?? so you mean it is multi-server?

            Well , In my GUI I can add client widgets and each one respective QTcpSocket client connects to a different remote server:

            client0 connects to server0
            client1 connects to server1
            client2 connects to server2
            and so on.

            Check the QtSimpleChatServer folder it manages multiple clients without blocking. Of course in that example it's just a console application but you are free to change it into a widget application with no changes to the core of the code.

            OK. I will.

            Thanks.

            JonBJ 1 Reply Last reply
            0
            • S simozz

              @VRonin said in What is the best approach to handle QTcpSocket (client connection) in a QThread ?:

              ?? so you mean it is multi-server?

              Well , In my GUI I can add client widgets and each one respective QTcpSocket client connects to a different remote server:

              client0 connects to server0
              client1 connects to server1
              client2 connects to server2
              and so on.

              Check the QtSimpleChatServer folder it manages multiple clients without blocking. Of course in that example it's just a console application but you are free to change it into a widget application with no changes to the core of the code.

              OK. I will.

              Thanks.

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by
              #6

              @simozz
              OK, this is unusual way round! I think @VRonin (and I) assumed your "handle many client connections" meant a server handling many clients. You actually have a "client" application which acts as many clients to many servers.

              I don't know whether you need separate threads or whether it can just act with multiple clients in main GUI thread and just handle each socket through slots...

              VRoninV 1 Reply Last reply
              0
              • JonBJ JonB

                @simozz
                OK, this is unusual way round! I think @VRonin (and I) assumed your "handle many client connections" meant a server handling many clients. You actually have a "client" application which acts as many clients to many servers.

                I don't know whether you need separate threads or whether it can just act with multiple clients in main GUI thread and just handle each socket through slots...

                VRoninV Offline
                VRoninV Offline
                VRonin
                wrote on last edited by VRonin
                #7

                @JonB said in What is the best approach to handle QTcpSocket (client connection) in a QThread ?:

                it can just act with multiple clients in main GUI thread and just handle each socket through slots

                It can. To demonstrate it, In the example, you can easily change https://github.com/VSRonin/ChatExample/blob/master/QtSimpleChatClient/clientmain.cpp adding, just before the return

                with:

                ChatWindow chatWin2;
                chatWin2.show();
                ChatWindow chatWin3;
                chatWin3.show();
                

                To have 3 clients on the same thread and all non blocking.

                "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                ~Napoleon Bonaparte

                On a crusade to banish setIndexWidget() from the holy land of Qt

                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