Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Special Interest Groups
  3. C++ Gurus
  4. How to write data to TcpSocket from another thread?
Forum Updated to NodeBB v4.3 + New Features

How to write data to TcpSocket from another thread?

Scheduled Pinned Locked Moved Solved C++ Gurus
11 Posts 3 Posters 3.5k Views 2 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
    Sencis
    wrote on last edited by
    #1

    On the computer work two thread. First, the Tcp server transfers data from the target PC to the UART. The second one checks the buffer for data (polling). UART is very slow so it is impossible to run everything in one thread. Need send data via Tcp Server to the target PC upon arrival of the data to UART, but when calling the write method to the port, the server drops to the records ( socket->write ( data ); ) or even so does not allow writing to the port ( socket->write ( "data" ); ). Where can I find documentation or an example to resolve this issue?

    UART the error happens after calling in the parse method of recording myserver.write():

    void UART_Protokol::ParseCommand()
    {
       MyServer myserver;
    
      if(sp_dataString == "Start") { TransmitData = "ready"; sp_Send(TransmitData); qDebug()<<"Self-test"; }
      if(sp_dataString == "ready") qDebug()<<"Self-test";
    
      if (sp_dataString =="MG1")  myserver.write("MG1");  //After the Debug message is displayed, the application crashes 
      if (sp_dataString =="MG0")  myserver.write("MG0");
      if (sp_dataString =="MG")  qDebug()<<"Calibration...";
    }
    

    Part of the Tcp server here is the method of writing MyServer::write at the very end:

    #include "myserver.h"
    
    
    MyServer::MyServer(){} 
    
    MyServer::~MyServer(){}
    
    
    
    
    void MyServer::startserver()
    
    {
        if (this->listen(QHostAddress::Any,8981))qDebug()<<"Server started";
        else{ qDebug()<<"Error started server";}
    
    }
    
    
    
    void MyServer::incomingConnection(int socketDescriptor ) 
    {
        socket = new QTcpSocket(this);
    
        socket->setSocketDescriptor( socketDescriptor);
    
        connect(socket,SIGNAL(readyRead()),this,SLOT(read())); 
        connect(socket,SIGNAL(disconnected()),this,SLOT(disconect())); 
    
        qDebug()<<socketDescriptor<<"Client connected";
    
        socket->write("Connection");
    
    }
    void MyServer::read()
    {
         UART_Protokol UART;
    
         UART.StartProtokol( false );
    
         arr = socket->readAll();
         data += arr;
    
    
          if ( data == "wu" )UART.sp_Send("wu");
          if ( data == "su" )UART.sp_Send("su");
          if ( data == "au" )UART.sp_Send("au");
          if ( data == "du" )UART.sp_Send("du");
          if ( data == "qu" )UART.sp_Send("qu");
          if ( data == "eu" )UART.sp_Send("eu");
          if ( data == "wd" )UART.sp_Send("wd");
          if ( data == "sd" )UART.sp_Send("sd");
          if ( data == "ad" )UART.sp_Send("ad");
          if ( data == "dd" )UART.sp_Send("dd");
          if ( data == "qd" )UART.sp_Send("qd");
          if ( data == "ed" )UART.sp_Send("ed");
          if (data == "SD1")UART.sp_Send("SD1");
          if (data == "SD0")UART.sp_Send("SD0");
          if (data == "cl")UART.sp_Send("cl");
    
          if( arr[0] == Mask[0]&& arr[1] == Mask[1])
          {
              int length = 0;
    
              QByteArray dt = "tr";
    
              trust[0] =0;
              trust[1] =0;
              trust[2] =0;
    
              length = arr[2];
              trust[0] =arr[3];
              trust[1] =arr[4];
              trust[2] =arr[5];
    
              truster = convert(trust, length - 48);
    
              dt[2] = truster;
    
              UART.sp_Send_integer(dt);
          }
    
          arr.clear(); 
          data = "";
    
    }
    
    void MyServer::disconect()
    
    { 
        socket->deleteLater();
    }
    
    
    void MyServer::write (QByteArray dat)
    {
      
     //An error occurs here
    
     qDebug()<<dat;  // Debug work is fine
    
     socket->write(dat);
    
    // it doesn't work too  socket->write ("MG1");
    
    }
    

    Just in case UART and TcpServer threads are started:

    #include <QCoreApplication>
    #include <myserver.h>
    #include <protokol_obmena_cherez_uart.h>
    #include <QDebug>
    #include <thread>
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        UART_Protokol Serial;
    
        Serial.StartProtokol( false );
    
        std::thread serial (&UART_Protokol::Event, Serial);  
    
        MyServer Server;
    
        Server.startserver();
    
        return a.exec();
    }
    
    1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi
      Could you not just use signal and slot ?
      So when UART has data it emit signal to MyServer to actually send some reply ?
      But im having hard time to understand the code as you seem to both
      make a UART_Protokol and Myserver in main but at the same time
      also make new one in void MyServer::read() and
      a server in void UART_Protokol::ParseCommand()
      so im not really sure what class should be talking to what class.

      1 Reply Last reply
      0
      • S Offline
        S Offline
        Sencis
        wrote on last edited by
        #3

        I've tried using the signal for the recording method but nothing either fail.

        It was necessary to create a new class to inherit Q_OBJECT otherwise the linker does not allow to use WiringPi for work with UART.

        
        class Signals: public QObject
        {
        
         Q_OBJECT
        
        public:
            Signals();
        
        
        public slots:
           void setValue();
        signals:
           void event_uart();
        
        };
        
        
        Signals::Signals(){}
        
        void Signals::setValue()
        {
          emit event_uart();
        }
        
        

        The MyServer::write slot does not work when sending a signal.

        void MyServer::incomingConnection(int socketDescriptor ) 
        {
            socket = new QTcpSocket(this);
        
            Signals ref;
        
            socket->setSocketDescriptor( socketDescriptor );
        
            connect(socket,SIGNAL(readyRead()),this,SLOT(read())); 
        
            connect(socket,SIGNAL(disconnected()),this,SLOT(disconect())); 
        
            connect(&ref,SIGNAL(event_uart()), this,SLOT(write()));  //connected signal with UART 
        
            qDebug()<<socketDescriptor<<"Client connected";
        
            socket->write("Connection");
        
        }
        
        void UART_Protokol::ParseCommand()
        {
        
           Signals ref;
        
          if(sp_dataString == "Start") { TransmitData = "ready"; sp_Send(TransmitData); qDebug()<<"Self-test"; }
          if(sp_dataString == "ready") qDebug()<<"Self-test";
        
          if (sp_dataString =="MG1")  { qDebug()<<"Start calibration..."; ref.setValue(); // send signal       }
          if (sp_dataString =="MG0")  { qDebug()<<"End calibration..."; ref.setValue();                                 }
          if (sp_dataString =="MG")   { qDebug()<<"Calibration...";                                            }
        }
        
        1 Reply Last reply
        0
        • mrjjM Offline
          mrjjM Offline
          mrjj
          Lifetime Qt Champion
          wrote on last edited by mrjj
          #4

          Hi
          I wonder about

          void MyServer::incomingConnection(int socketDescriptor ) 
          {
              socket = new QTcpSocket(this);
          
              Signals ref; // this is local object and will be deleted as soon as function ends
          
              socket->setSocketDescriptor( socketDescriptor );
          
              connect(socket,SIGNAL(readyRead()),this,SLOT(read())); 
          
              connect(socket,SIGNAL(disconnected()),this,SLOT(disconect())); 
          
              connect(&ref,SIGNAL(event_uart()), this,SLOT(write()));  //connected signal with UART 
          
              qDebug()<<socketDescriptor<<"Client connected";
          
              socket->write("Connection");
          
          }
          

          Since Signals ref; is gone as soon as function ends, how will it ever emit event_uart()
          once data arrives ?

          i was expecting something like

          int main(int argc, char *argv[])
          {
              QCoreApplication a(argc, argv);
          
              UART_Protokol Serial;
              Serial.StartProtokol( false );
             std::thread serial (&UART_Protokol::Event, Serial);  
          
              MyServer Server;
             connect(&Serial, UART_Protokol::ServerWrite, &Server, MyServer::write, Qt::QueuedConnection); // or similar
           
              Server.startserver();
          
              return a.exec();
          }
          
          and then in (and other places )
          void UART_Protokol::ParseCommand()
          {
          // MyServer myserver; // why make a new local server when you have one in main ??
          .....
            if (sp_dataString =="MG1")  emit ServerWrite("MG1");  //emit signal to server in main
          .....
          }
          
          
          1 Reply Last reply
          3
          • S Offline
            S Offline
            Sencis
            wrote on last edited by Sencis
            #5

            I can't use the emit ServerWrite signal because I need UART_Protokol class inherit to the QObject class without this will be error when creating the signal slot. But i cannot inherit this class because the linker throws an error.

            class UART_Protokol
            {
            
             Q_OBJECT //If i inherit QObject to the UART_Protokol: undefined reference to `vtable for UART_Protokol'
            
            //And without Q_OBJECT I can't use signals
            
            signals:
            
              void ServerWrite (QByteArray dat);
            

            Is this how it's gonna work? Can I use a signal from another class?

            QObject::connect (&signal,&Signals::setValue, &Server,&MyServer::write, Qt::QueuedConnection);
            
            
            1 Reply Last reply
            0
            • mrjjM Offline
              mrjjM Offline
              mrjj
              Lifetime Qt Champion
              wrote on last edited by
              #6

              HI
              Cant you just do
              class UART_Protokol : public QObject
              {
              Q_OBJECT
              ...

              ah,
              undefined reference to `vtable for UART_Protokol'

              thats happens often.
              just inherit from QObject
              then clean all of build folder
              and then rebuild all.
              Its a known error coming from not all is recompiled after adding QObject

              1 Reply Last reply
              2
              • S Offline
                S Offline
                Sencis
                wrote on last edited by
                #7

                I cleaned up the entire contents of the folder and reassembled everything. Error appeared: "Class contains Q_OBJECT macro but does not inherit from QObject ":

                /#ifndef PROTOKOL_OBMENA_CHEREZ_UART_H
                #define PROTOKOL_OBMENA_CHEREZ_UART_H
                #include <QString>
                #include <thread>
                #include <myserver.h>
                #include <QObject>
                
                class UART_Protokol 
                {
                
                 Q_OBJECT
                

                If inherit a class from QObject how in other example, other errors occur:

                #ifndef PROTOKOL_OBMENA_CHEREZ_UART_H
                #define PROTOKOL_OBMENA_CHEREZ_UART_H
                #include <QString>
                #include <thread>
                #include <myserver.h>
                #include <QObject>
                
                class UART_Protokol : public QObject
                {
                
                 Q_OBJECT
                

                use of deleted function ‘UART_Protokol::UART_Protokol(const UART_Protokol&)’
                : _M_head_impl(std::forward<_UHead>(__h)) { }

                ‘QObject::QObject(const QObject&)’ is private within this context

                use of deleted function ‘QObject::QObject(const QObject&)’
                class UART_Protokol : public QObject
                ^~~~~~~~~~~~~
                ^
                no matching function for call to ‘std::tuple<std::_Mem_fn<void (UART_Protokol::)()>, UART_Protokol>::tuple(std::_Mem_fn<void (UART_Protokol::)()>, UART_Protokol&)’
                : _M_bound(std::forward<_Tp>(__f), std::forward<_Up>(__args)...)
                ^

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

                  Hi,

                  That means that you are trying to copy an instance of your object which is not possible with QObject based classes.

                  See here for more information.

                  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
                  2
                  • S Offline
                    S Offline
                    Sencis
                    wrote on last edited by Sencis
                    #9

                    If I inherit the class :

                    class UART_Protokol : public QObject
                    {
                    
                        Q_OBJECT
                    

                    and comment on a thread, everything is going without errors:

                    // std::thread serial (&UART_Protokol::Event, Serial); 
                    
                    // serial.detach();
                    
                    

                    even connecting signal to slot, build is fine:

                    QObject::connect (&Serial,&UART_Protokol::ServerWrite, &Server,&MyServer::write, Qt::QueuedConnection);
                    

                    That's just it I need to check the UART buffer for reading messages.

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

                      Did you read the document I linked regarding copying QObject based classes ?

                      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 Offline
                        S Offline
                        Sencis
                        wrote on last edited by
                        #11

                        Thank you all for your help, the signals really work fine and now i can easily pass the calibration data of the magnetometer! The truth is everything works in one thread with a timer but the delay is not big.

                        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