Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

TCP client and QThread facing issue



  • I am trying to send the data from the QThread through QTCPSocket . I connect to server from main window and get a data from the user and when the user presses the sen botton i start the thread and inside the run() i have called another function that transmits the user entered data . But the problem is it is not transmitting .
    (Note: both the functions are inside a QThread)

    inside run()
              {
                  SendData(data);
               }
    
    
    sendData(Qstring str)
     {
      QTcpSocket tcpSocket;
    
        QByteArray arrBlock;
        QDataStream out(&arrBlock, QIODevice::WriteOnly);
        //out.setVersion(QDataStream::Qt_5_10);
        out << quint16(0) << str;
    
        out.device()->seek(0);
        out << quint16(arrBlock.size() - sizeof(quint16));
       qDebug("%s",str.toLatin1().data());
    
        tcpSocket.write(arrBlock);
     }

  • Lifetime Qt Champion

    @ManiRon said in TCP client and QThread facing issue:

    QTcpSocket tcpSocket;

    Where do you connect this socket?!
    In this piece of code you don't - how can it work?


  • Moderators

    @ManiRon said in TCP client and QThread facing issue:

    I am trying to send the data from the QThread through QTCPSocket .

    First, I suggest you try to send the data from your main thread. After that, decide if you need a thread or not.

    Anyway, @jsulm has identified your main problem: You haven't told your QTcpSocket where to transmit the data.

    See the examples to get started:



  • @jsulm

    void MainWindow::on_pushButton_connect_clicked()
    {
    client->connect2host();
    }


  • Lifetime Qt Champion

    @ManiRon This tcpSocket is a LOCAL variable and for sure not what you call in on_pushButton_connect_clicked():

    sendData(Qstring str)
     {
      QTcpSocket tcpSocket; // This is a LOCAL variable!
    

    And I really don't get it: I asked about "tcpSocket" and you're writing something about "client"?

    Also it is called connectToHost not connect2Host.



  • @jsulm

    MyThread.cpp

                     TestThread::TestThread()
                     {
    
                      }
    
                void TestThread :: run()
                 {
       
                    qDebug("%s",s.toLatin1().data());
                   sendData(s);
                   }
               void TestThread :: sendData(QString str)
                {
               QByteArray arrBlock;
            QDataStream out(&arrBlock, QIODevice::WriteOnly);
            //out.setVersion(QDataStream::Qt_5_10);
            out << quint16(0) << str;
    
            out.device()->seek(0);
            out << quint16(arrBlock.size() - sizeof(quint16));
               qDebug("%s",str.toLatin1().data());
    
            tcpSocket1->write(arrBlock);
    
           }
    

    Myclient.cpp

    ClientStuff::ClientStuff(
            const QString hostAddress,
            int portNumber,
            QObject *parent
            ) : QObject(parent), m_nNextBlockSize(0)
    {
        status = false;
    
        host = hostAddress;
        port = portNumber;
    
        tcpSocket = new QTcpSocket(this);
        connect(tcpSocket, &QTcpSocket::disconnected, this, &ClientStuff::closeConnection);
    
        timeoutTimer = new QTimer();
        timeoutTimer->setSingleShot(true);
        connect(timeoutTimer, &QTimer::timeout, this, &ClientStuff::connectionTimeout);
    }
    
    void ClientStuff::connect2host()
    {
        timeoutTimer->start(3000);
    
        tcpSocket->connectToHost(host, port);
        connect(tcpSocket, &QTcpSocket::connected, this, &ClientStuff::connected);
        connect(tcpSocket, &QTcpSocket::readyRead, this, &ClientStuff::readyRead);
    }
    
    void ClientStuff::connectionTimeout()
    {
        //qDebug() << tcpSocket->state();
        if(tcpSocket->state() == QAbstractSocket::ConnectingState)
        {
            tcpSocket->abort();
            emit tcpSocket->error(QAbstractSocket::SocketTimeoutError);
        }
    }
    
    void ClientStuff::connected()
    {
        status = true;
        emit statusChanged(status);
    }
    
    bool ClientStuff::getStatus() {return status;}
    
    void ClientStuff::readyRead()
    {
        QDataStream in(tcpSocket);
        for (;;)
        {
            if (!m_nNextBlockSize)
            {
                if (tcpSocket->bytesAvailable() < sizeof(quint16)) { break; }
                in >> m_nNextBlockSize;
            }
    
            if (tcpSocket->bytesAvailable() < m_nNextBlockSize) { break; }
    
            QString str; in >> str;
    
            if (str == "0")
            {
                str = "Connection closed";
                closeConnection();
            }
    
            emit hasReadSome(str);
            m_nNextBlockSize = 0;
        }
    }
    
    
    
    void ClientStuff::closeConnection()
    {
        timeoutTimer->stop();
    
        //qDebug() << tcpSocket->state();
        disconnect(tcpSocket, &QTcpSocket::connected, 0, 0);
        disconnect(tcpSocket, &QTcpSocket::readyRead, 0, 0);
    
        bool shouldEmit = false;
        switch (tcpSocket->state())
        {
            case 0:
                tcpSocket->disconnectFromHost();
                shouldEmit = true;
                break;
            case 2:
                tcpSocket->abort();
                shouldEmit = true;
                break;
            default:
                tcpSocket->abort();
        }
    
        if (shouldEmit)
        {
            status = false;
            emit statusChanged(status);
        }
    }
    

    MainWindow.cpp

    MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        ui->pushButton_disconnect->setVisible(false);
    
        client = new ClientStuff("localhost", 6547);
    
        setStatus(client->getStatus());
    
        set = new TestThread ;
    
        connect(client, &ClientStuff::hasReadSome, this, &MainWindow::receivedSomething);
        connect(client, &ClientStuff::statusChanged, this, &MainWindow::setStatus);
        // FIXME change this connection to the new syntax
        connect(tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)),
                this, SLOT(gotError(QAbstractSocket::SocketError)));
    }
    
    MainWindow::~MainWindow()
    {
        delete client;
        delete ui;
    }
    
    void MainWindow::setStatus(bool newStatus)
    {
        if(newStatus)
        {
            ui->label_status->setText(
                        tr("<font color=\"green\">CONNECTED</font>"));
            ui->pushButton_connect->setVisible(false);
            ui->pushButton_disconnect->setVisible(true);
        }
        else
        {
            ui->label_status->setText(
                    tr("<font color=\"red\">DISCONNECTED</font>"));
            ui->pushButton_connect->setVisible(true);
            ui->pushButton_disconnect->setVisible(false);
        }
    }
    
    void MainWindow::receivedSomething(QString msg)
    {
        ui->textEdit_log->append(msg);
    }
    
    void MainWindow::gotError(QAbstractSocket::SocketError err)
    {
        //qDebug() << "got error";
        QString strError = "unknown";
        switch (err)
        {
            case 0:
                strError = "Connection was refused";
                break;
            case 1:
                strError = "Remote host closed the connection";
                break;
            case 2:
                strError = "Host address was not found";
                break;
            case 5:
                strError = "Connection timed out";
                break;
            default:
                strError = "Unknown error";
        }
    
        ui->textEdit_log->append(strError);
    }
    
    void MainWindow::on_pushButton_connect_clicked()
    {
        client->connect2host();
    }
    
    void MainWindow::on_pushButton_send_clicked()
    {
    
    
    
    
    
        set->s = ui->lineEdit_message->text();
        
        set->start();
        
    
    }
    
    void MainWindow::on_pushButton_disconnect_clicked()
    {
        client->closeConnection();
    }
    

  • Moderators

    @ManiRon
    oh dear,
    this is a mess!
    You have 3 different QTcpSockets instances in 3 classes.
    And on top of that your QThread approach is at the very least unflattering.

    I would suggest, make your very own capsuled tcp-communication class with one instance of QTcpSocket -object.
    Make sure it works and than think if you really need a thread for it or not. If you want/need one, you can very simply move your communication class to that thread.


  • Qt Champions 2017

    My advice: read first, it's more important and bears fruit in the long run, code later.

    @J.Hilk said in TCP client and QThread facing issue:

    I would suggest, make your very own capsuled tcp-communication class with one instance of QTcpSocket -object.

    Like it's done here.



  • @J.Hilk @kshegunov

    I am looking for sample program for client. In which client is connected from one thread and transmission and receiving of data through same client from another thread. is there any sample , if yes kindly share the link .



  • @ManiRon said in TCP client and QThread facing issue:

    if yes kindly share the link .

    @kshegunov said in TCP client and QThread facing issue:

    Like it's done here.


Log in to reply