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. QTcpSocket Write
Forum Updated to NodeBB v4.3 + New Features

QTcpSocket Write

Scheduled Pinned Locked Moved Unsolved General and Desktop
qt5qtcpsocketqthreadqtimer
8 Posts 4 Posters 1.5k 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.
  • D Offline
    D Offline
    duckrae
    wrote on last edited by duckrae
    #1

    Hi, I want to ask something about QTcpSocket Write.

    QT application for TCP server, Sensor for TCP client.

    Myserver Class start MyThread.

    void Myserver::startServer()
    {
        int port = 3333;
    
        if(!this->listen(QHostAddress::Any,port))
        {
            qDebug() << "Could not start server";
        }
        else
        {
            qDebug() << "Listening to port " << port << "...";
        }
    }
    
    void Myserver::incomingConnection(qintptr socketDescriptor)
    {
        // We have a new connection
        qDebug() << socketDescriptor << " Connecting...";
    
        MyThread *thread = new MyThread(socketDescriptor, this);
    
        // connect signal/slot
        // once a thread is not needed, it will be beleted later
        connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
        connect(thread, SIGNAL(connectValue(int)), this, SLOT(peerConnectionValue(int)));
        connect(thread, SIGNAL(disconnectValue(int)), this, SLOT(peerDisconnectionValue(int)));
        connect(thread, SIGNAL(sendFirstSensorData(QString)), this, SLOT(peerSendFirstSensorData(QString)));
        connect(thread, SIGNAL(sendSecondSensorData(QString)), this, SLOT(peerSendSecondSensorData(QString)));
        connect(thread, SIGNAL(sendThirdSensorData(QString)), this, SLOT(peerSendThirdSensorData(QString)));
        connect(thread, SIGNAL(sendFourthSensorData(QString)), this, SLOT(peerSendFourthSensorData(QString)));
    
    
        thread->start();
    }
    

    In QThread Class,

    #include "mythread.h"
    
    #include <QThread>
    #include <QTimer>
    #include <QTime>
    #include <QFile>
    #include <QString>
    #include <QTextStream>
    
    MyThread::MyThread(qintptr ID, QObject *parent) :
        QThread(parent)
    {
        this->socketDescriptor = ID;
    }
    
    void MyThread::run()
    {
        // thread starts here
        qDebug() << " Thread started";
    
        socket = new QTcpSocket();
    
        // set the ID
        if(!socket->setSocketDescriptor(this->socketDescriptor))
        {
            // something's wrong, we just emit a signal
            emit error(socket->error());
            return;
        }
        qRegisterMetaType<QAbstractSocket::SocketState>();
        // connect socket and signal
        // note - Qt::DirectConnection is used because it's multithreaded
        //        This makes the slot to be invoked immediately, when the signal is emitted.
    
        connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()), Qt::DirectConnection);
        connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()));
        connect(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(HandleStateChange(QAbstractSocket::SocketState)));
    
        // We'll have multiple clients, we want to know which is which
        qDebug() << socketDescriptor << "Client connected";
        
        QByteArray firstSensorId = QByteArray::fromHex("F0 F1 32 30 30 36 30 30 30 32 35 35 30 30 32 F3 F4");
        QByteArray secondSensorId = QByteArray::fromHex("F0 F1 32 30 30 36 30 30 31 32 35 35 30 30 33 F3 F4");
        QByteArray thirdSensorId = QByteArray::fromHex("F0 F1 32 30 30 36 30 30 32 32 35 35 30 30 30 F3 F4");
        QByteArray fourthSensorId = QByteArray::fromHex("F0 F1 32 30 30 36 30 30 33 32 35 35 30 30 31 F3 F4");
    
        socket->write(firstSensorId);
        socket->write(secondSensorId);
        socket->write(thirdSensorId);
        socket->write(fourthSensorId);
    
        // First, If tcp protocol connected, we have to send packet for knowing what sensor was connected. So, you have to send four packets.
    
    //    QString strValue = QString::number(socketDescriptor);
    
    //    emit sendValue(strValue);
    
        // make this thread a loop,
        // thread will stay alive so that signal/slot to function properly
        // not dropped out in the middle when thread dies
    
    
        exec();
    }
    
    void MyThread::readyRead()
    {
    
        // get the information
        Data = socket->readAll();
        // will write on server side window
        qDebug() << Data;
        QString raw(Data);
        raw.remove(0,9);
        QString sensorId = raw.left(3);
        qDebug() << sensorId;
        MyThread::msleep(500);
        if(Data == nullptr){
            emit disconnectValue(1);
        }
        if(Data != nullptr) {
            QString compareId(Data);
            compareId.remove(0,12);
            compareId.chop(26);
            qDebug() << compareId;
            QByteArray firstSensorData = QByteArray::fromHex("F0 F1 34 30 30 36 30 30 30 32 35 35 30 30 32 F3 F4");
            QByteArray secondSensorData = QByteArray::fromHex("F0 F1 34 30 30 36 30 30 31 32 35 35 30 30 33 F3 F4");
            QByteArray thirdSensorData = QByteArray::fromHex("F0 F1 34 30 30 36 30 30 32 32 35 35 30 30 30 F3 F4");
            QByteArray fourthSensorData = QByteArray::fromHex("F0 F1 34 30 30 36 30 30 33 32 35 35 30 30 31 F3 F4");
    
            if(sensorId.endsWith("000")){
                emit connectValue(1);
                emit sendFirstSensorData(compareId);
                socket->write(firstSensorData);
            } else if(sensorId.endsWith("001")){
                emit connectValue(2);
                emit sendSecondSensorData(compareId);
                socket->write(secondSensorData);
            } else if(sensorId.endsWith("002")){
                emit connectValue(3);
                emit sendThirdSensorData(compareId);
                socket->write(thirdSensorData);
            } else if(sensorId.endsWith("003")){
                emit connectValue(4);
                emit sendFourthSensorData(compareId);
                socket->write(fourthSensorData);
            }
        }
    }
    
    void MyThread::disconnected()
    {
        qDebug() << socketDescriptor << " Disconnected";
        socket->deleteLater();
        exit(0);
    }
    
    void MyThread::HandleStateChange(QAbstractSocket::SocketState state){
        qDebug() << state;
    }
    
    

    This is my question.

    When socket readyread() not working or Server not write packet to Client,

    Client not give back sensor value to Server. Because Client only write sensor value when receive packet from server.

    I want Server write packet not in readyread(). readyread() must be working. Because Server have to receive client sensor Value.

    Now, only readyread() function write to socket. But I want write to socket from another function in Mythread class.

    1. Can I connect SIGNAL/SLOT Myserver to MyThread.readyread()? I already connected and emit in Myserver. and
      socket notifiers cannot be enabled or disabled from another thread -> this error occurred.

    2. Can I use QTimer in MyThread Class?
      cannot create children for a parent that is in a different thread -> this error occurred.

    3. Is there any way?

    jsulmJ 1 Reply Last reply
    0
    • D duckrae

      Hi, I want to ask something about QTcpSocket Write.

      QT application for TCP server, Sensor for TCP client.

      Myserver Class start MyThread.

      void Myserver::startServer()
      {
          int port = 3333;
      
          if(!this->listen(QHostAddress::Any,port))
          {
              qDebug() << "Could not start server";
          }
          else
          {
              qDebug() << "Listening to port " << port << "...";
          }
      }
      
      void Myserver::incomingConnection(qintptr socketDescriptor)
      {
          // We have a new connection
          qDebug() << socketDescriptor << " Connecting...";
      
          MyThread *thread = new MyThread(socketDescriptor, this);
      
          // connect signal/slot
          // once a thread is not needed, it will be beleted later
          connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
          connect(thread, SIGNAL(connectValue(int)), this, SLOT(peerConnectionValue(int)));
          connect(thread, SIGNAL(disconnectValue(int)), this, SLOT(peerDisconnectionValue(int)));
          connect(thread, SIGNAL(sendFirstSensorData(QString)), this, SLOT(peerSendFirstSensorData(QString)));
          connect(thread, SIGNAL(sendSecondSensorData(QString)), this, SLOT(peerSendSecondSensorData(QString)));
          connect(thread, SIGNAL(sendThirdSensorData(QString)), this, SLOT(peerSendThirdSensorData(QString)));
          connect(thread, SIGNAL(sendFourthSensorData(QString)), this, SLOT(peerSendFourthSensorData(QString)));
      
      
          thread->start();
      }
      

      In QThread Class,

      #include "mythread.h"
      
      #include <QThread>
      #include <QTimer>
      #include <QTime>
      #include <QFile>
      #include <QString>
      #include <QTextStream>
      
      MyThread::MyThread(qintptr ID, QObject *parent) :
          QThread(parent)
      {
          this->socketDescriptor = ID;
      }
      
      void MyThread::run()
      {
          // thread starts here
          qDebug() << " Thread started";
      
          socket = new QTcpSocket();
      
          // set the ID
          if(!socket->setSocketDescriptor(this->socketDescriptor))
          {
              // something's wrong, we just emit a signal
              emit error(socket->error());
              return;
          }
          qRegisterMetaType<QAbstractSocket::SocketState>();
          // connect socket and signal
          // note - Qt::DirectConnection is used because it's multithreaded
          //        This makes the slot to be invoked immediately, when the signal is emitted.
      
          connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()), Qt::DirectConnection);
          connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()));
          connect(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(HandleStateChange(QAbstractSocket::SocketState)));
      
          // We'll have multiple clients, we want to know which is which
          qDebug() << socketDescriptor << "Client connected";
          
          QByteArray firstSensorId = QByteArray::fromHex("F0 F1 32 30 30 36 30 30 30 32 35 35 30 30 32 F3 F4");
          QByteArray secondSensorId = QByteArray::fromHex("F0 F1 32 30 30 36 30 30 31 32 35 35 30 30 33 F3 F4");
          QByteArray thirdSensorId = QByteArray::fromHex("F0 F1 32 30 30 36 30 30 32 32 35 35 30 30 30 F3 F4");
          QByteArray fourthSensorId = QByteArray::fromHex("F0 F1 32 30 30 36 30 30 33 32 35 35 30 30 31 F3 F4");
      
          socket->write(firstSensorId);
          socket->write(secondSensorId);
          socket->write(thirdSensorId);
          socket->write(fourthSensorId);
      
          // First, If tcp protocol connected, we have to send packet for knowing what sensor was connected. So, you have to send four packets.
      
      //    QString strValue = QString::number(socketDescriptor);
      
      //    emit sendValue(strValue);
      
          // make this thread a loop,
          // thread will stay alive so that signal/slot to function properly
          // not dropped out in the middle when thread dies
      
      
          exec();
      }
      
      void MyThread::readyRead()
      {
      
          // get the information
          Data = socket->readAll();
          // will write on server side window
          qDebug() << Data;
          QString raw(Data);
          raw.remove(0,9);
          QString sensorId = raw.left(3);
          qDebug() << sensorId;
          MyThread::msleep(500);
          if(Data == nullptr){
              emit disconnectValue(1);
          }
          if(Data != nullptr) {
              QString compareId(Data);
              compareId.remove(0,12);
              compareId.chop(26);
              qDebug() << compareId;
              QByteArray firstSensorData = QByteArray::fromHex("F0 F1 34 30 30 36 30 30 30 32 35 35 30 30 32 F3 F4");
              QByteArray secondSensorData = QByteArray::fromHex("F0 F1 34 30 30 36 30 30 31 32 35 35 30 30 33 F3 F4");
              QByteArray thirdSensorData = QByteArray::fromHex("F0 F1 34 30 30 36 30 30 32 32 35 35 30 30 30 F3 F4");
              QByteArray fourthSensorData = QByteArray::fromHex("F0 F1 34 30 30 36 30 30 33 32 35 35 30 30 31 F3 F4");
      
              if(sensorId.endsWith("000")){
                  emit connectValue(1);
                  emit sendFirstSensorData(compareId);
                  socket->write(firstSensorData);
              } else if(sensorId.endsWith("001")){
                  emit connectValue(2);
                  emit sendSecondSensorData(compareId);
                  socket->write(secondSensorData);
              } else if(sensorId.endsWith("002")){
                  emit connectValue(3);
                  emit sendThirdSensorData(compareId);
                  socket->write(thirdSensorData);
              } else if(sensorId.endsWith("003")){
                  emit connectValue(4);
                  emit sendFourthSensorData(compareId);
                  socket->write(fourthSensorData);
              }
          }
      }
      
      void MyThread::disconnected()
      {
          qDebug() << socketDescriptor << " Disconnected";
          socket->deleteLater();
          exit(0);
      }
      
      void MyThread::HandleStateChange(QAbstractSocket::SocketState state){
          qDebug() << state;
      }
      
      

      This is my question.

      When socket readyread() not working or Server not write packet to Client,

      Client not give back sensor value to Server. Because Client only write sensor value when receive packet from server.

      I want Server write packet not in readyread(). readyread() must be working. Because Server have to receive client sensor Value.

      Now, only readyread() function write to socket. But I want write to socket from another function in Mythread class.

      1. Can I connect SIGNAL/SLOT Myserver to MyThread.readyread()? I already connected and emit in Myserver. and
        socket notifiers cannot be enabled or disabled from another thread -> this error occurred.

      2. Can I use QTimer in MyThread Class?
        cannot create children for a parent that is in a different thread -> this error occurred.

      3. Is there any way?

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

      @duckrae Are you sure you need threads?
      Qt is an assynchronous framework. You can use QTcpSocket without threads and without blocking the main thread.
      Threads lead to more complex code and it is very easy to use them wrongly.

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

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

        Threads are not needed here at all. Also where do you create your 'socket' ?

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

        D 1 Reply Last reply
        0
        • jsulmJ jsulm

          @duckrae Are you sure you need threads?
          Qt is an assynchronous framework. You can use QTcpSocket without threads and without blocking the main thread.
          Threads lead to more complex code and it is very easy to use them wrongly.

          D Offline
          D Offline
          duckrae
          wrote on last edited by
          #4

          @jsulm Thanks for answer. If I had time, I could study more, but I don't have time. In this code, is there any way to solve this problem?

          jsulmJ 1 Reply Last reply
          0
          • D duckrae

            @jsulm Thanks for answer. If I had time, I could study more, but I don't have time. In this code, is there any way to solve this problem?

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

            @duckrae said in QTcpSocket Write:

            but I don't have time

            If you don't have time then remove the threading stuff to make the code easier and avoid doing things wrong as you already do (see "cannot create children for a parent that is in a different thread").

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

            1 Reply Last reply
            1
            • Christian EhrlicherC Christian Ehrlicher

              Threads are not needed here at all. Also where do you create your 'socket' ?

              D Offline
              D Offline
              duckrae
              wrote on last edited by
              #6

              @Christian-Ehrlicher Thanks for answer. I edited code. I have to connect with 4 client. How to connect multi client without thread? I already do without thread, but it connect only one on one

              jsulmJ A 2 Replies Last reply
              0
              • D duckrae

                @Christian-Ehrlicher Thanks for answer. I edited code. I have to connect with 4 client. How to connect multi client without thread? I already do without thread, but it connect only one on one

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

                @duckrae said in QTcpSocket Write:

                I already do without thread, but it connect only one on one

                Keep one socket for each connection. If it does not work show the code.
                You can also take a look at https://doc.qt.io/qt-5/qtnetwork-fortuneserver-example.html

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

                1 Reply Last reply
                1
                • D duckrae

                  @Christian-Ehrlicher Thanks for answer. I edited code. I have to connect with 4 client. How to connect multi client without thread? I already do without thread, but it connect only one on one

                  A Offline
                  A Offline
                  anil_arise
                  wrote on last edited by
                  #8

                  @duckrae List your client with id, when you are getting new incomingConnection. server can reply as per client id to a specific client or reply to all.

                  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