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. How QTcpSocket Asynchronous return taskreult to each socket
Forum Updated to NodeBB v4.3 + New Features

How QTcpSocket Asynchronous return taskreult to each socket

Scheduled Pinned Locked Moved Solved General and Desktop
4 Posts 3 Posters 436 Views 1 Watching
  • 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
    Shao
    wrote on last edited by
    #1

    Hi,
    I follow the website to implement the Asynchronous Task for socket.

    void MyClient::readyRead()
    {
        qDebug() << "MyClient::readyRead()";
        qDebug() << socket->readAll();
    
        // Time consumer
        MyTask *mytask = new MyTask();
        mytask->setAutoDelete(true);
        
        // using queued connection
        connect(mytask, SIGNAL(Result(int)), this, SLOT(TaskResult(int)), Qt::QueuedConnection);
    
        qDebug() << "Starting a new task using a thread from the QThreadPool";
        
        // QThreadPool::globalInstance() returns global QThreadPool instance
        QThreadPool::globalInstance()->start(mytask);
    
    }
    
    // After a task performed a time consuming task,
    // we grab the result here, and send it to client
    void MyClient::TaskResult(int Number)
    {
        QByteArray Buffer;
        Buffer.append("\r\nTask result = ");
        Buffer.append(QString::number(Number));
    
        socket->write(Buffer);
    }
    

    My problem is the task result will send to each client that is waiting for the task result
    For Example:
    The task result needs 3s to finish and return. Now, there are multiple clients are created.
    The 1st client requires task results at 0s.
    The 2nd client requires task results at 1s.
    At the 3s, The task finish sends the signal Result() of the 1st client.
    The 1st and 2nd client will receive the signal and do the socket->write()

    It's there a way to avoid this situation?
    My only idea is to pass socket information to the task.
    When the task is finished, it passes the required socket information to the client.
    The client should check the task result which is it required or not by socket information.

    Is there any other better method or advice?

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

      Hi,

      You should map your tasks with the socket it shall report to. That way when the task is done you can retrieve the appropriate socket and then write the result to it.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      1
      • S Shao

        Hi,
        I follow the website to implement the Asynchronous Task for socket.

        void MyClient::readyRead()
        {
            qDebug() << "MyClient::readyRead()";
            qDebug() << socket->readAll();
        
            // Time consumer
            MyTask *mytask = new MyTask();
            mytask->setAutoDelete(true);
            
            // using queued connection
            connect(mytask, SIGNAL(Result(int)), this, SLOT(TaskResult(int)), Qt::QueuedConnection);
        
            qDebug() << "Starting a new task using a thread from the QThreadPool";
            
            // QThreadPool::globalInstance() returns global QThreadPool instance
            QThreadPool::globalInstance()->start(mytask);
        
        }
        
        // After a task performed a time consuming task,
        // we grab the result here, and send it to client
        void MyClient::TaskResult(int Number)
        {
            QByteArray Buffer;
            Buffer.append("\r\nTask result = ");
            Buffer.append(QString::number(Number));
        
            socket->write(Buffer);
        }
        

        My problem is the task result will send to each client that is waiting for the task result
        For Example:
        The task result needs 3s to finish and return. Now, there are multiple clients are created.
        The 1st client requires task results at 0s.
        The 2nd client requires task results at 1s.
        At the 3s, The task finish sends the signal Result() of the 1st client.
        The 1st and 2nd client will receive the signal and do the socket->write()

        It's there a way to avoid this situation?
        My only idea is to pass socket information to the task.
        When the task is finished, it passes the required socket information to the client.
        The client should check the task result which is it required or not by socket information.

        Is there any other better method or advice?

        jsulmJ Offline
        jsulmJ Offline
        jsulm
        Lifetime Qt Champion
        wrote on last edited by
        #2

        @Shao I don't understand your description (it is really unclear). I also don't understand your code: why do you call readAll() to output it to qDebug?! After readAll() there is no data anymore to read - don't you want to use it? I also don''t understand why you're creating a new MyTask each time readyRead() is called! readyRead() can be called several times for one package sent! I also don't see how you're handling different client connections...

        Please try to explain better what you actually want to achieve.

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

        1 Reply Last reply
        2
        • S Offline
          S Offline
          Shao
          wrote on last edited by Shao
          #3

          Hi @jsulm

          Here is my code

          ControlServer.cpp

          #include "controlserver.h"
          #include <iostream>
          
          using namespace std;
          
          ControlServer::ControlServer(int _port, QObject *parent):port(_port)
          {
              setParent(parent);
          }
          
          bool ControlServer::startServer()
          {
              bool ret = this->listen(QHostAddress::Any, port);
              if(ret){
                  cout << "start control server"<<endl;
              }
              else{
                  cout << "control server start failed"<<endl;
              }
              return ret;
          }
          
          void ControlServer::bindProgrammer(PROGRAMMER *_programmer)
          {
              mProgrammer = _programmer;
          }
          
          // ****create client for each connection****
          void ControlServer::incomingConnection(qintptr handle)
          {
              cout << handle<<endl;
              ControlSocket *mControlSocket = new ControlSocket(this);
              mControlSocket->setSocket(handle);
              mControlSocket->setProgrammer(mProgrammer); // serial port device
          }
          

          ControlSocket.cpp

          ControlSocket::ControlSocket(QObject *parent):MySocket(parent)
          {
              QThreadPool::globalInstance()->setMaxThreadCount(5);
          }
          
          void ControlSocket::setProgrammer(PROGRAMMER *_programmer)
          {
              mProgrammer = _programmer;
          }
          
          
          // **** readyRead create and assign task 
          void ControlSocket::readyRead()
          {
              QByteArray data = this->socket->readAll();
          
              // Time consumer
              MyControlTask *mControlTask = new MyControlTask(mProgrammer, data);
              mControlTask->setAutoDelete(true);
              connect(mControlTask, SIGNAL(result(QByteArray)), this, SLOT(TaskResult(QByteArray)), Qt::QueuedConnection);
              QThreadPool::globalInstance()->start(mControlTask);
              cout << data.data() <<endl;
          }
          
          
          void ControlSocket::TaskResult(QByteArray data)
          {
              cout << __func__ << data.data()<<endl;
              data.push_front("echo:");
              socket->write(data);
          }
          

          MyControlTask.cpp

          #include "mycontroltask.h"
          #include <iostream>
          #include <QThread>
          
          using namespace std;
          MyControlTask::MyControlTask(PROGRAMMER *_programmer, QByteArray _cmd, QObject *parent):mProgrammer(_programmer), mCmd(_cmd)
          {
              connect(this, SIGNAL(transferToProgrammer(QByteArray)), mProgrammer, SLOT(sendToUart(QByteArray)));
              connect(mProgrammer, SIGNAL(EchoToTask(QByteArray)), this, SLOT(ProgrammerToTask(QByteArray)));
          }
          
          void MyControlTask::ProgrammerToTask(QByteArray data)
          {
              cout <<"ProgrammerToTask" << data.data()<<endl;
              emit(result(data));
          }
          
          void MyControlTask::run()
          {
              cout << "Run:" << mCmd.data()<<endl;
              emit(transferToProgrammer(mCmd));  //emit signal to trigger 
          
              // since the mProgrammer is also 
              QThread::usleep(10000000);
          }
          

          The main step in controlscoket as below

          1. read data and store
          2. create task with mProgrammer (a SerialPort device) and data (each socket client will connect to the same mProgrammer(serialPort Device)
          3. connect mProgrammer result signal to this task Result
          4. start task to parsing data and do something depending on the decoding result
          5. wait to TaskResult and socket write to client with the result

          I am confused in step 2~5.
          For each data, I will create a task to do something.
          If the first task is unfinished, I create the second task.
          And then the first task finsish and emit the signal "result(QByteArray)" to trigger taskResult slot.
          The first and second client will be trigger slot.
          But the taskResult is not matter about second socket client.

          1 Reply Last reply
          0
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #4

            Hi,

            You should map your tasks with the socket it shall report to. That way when the task is done you can retrieve the appropriate socket and then write the result to it.

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply
            1

            • Login

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