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); }
-
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); }
@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? -
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); }
@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:
-
@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? -
@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.
-
@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.
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(); }
-
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(); }
@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. -
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(); }
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.
-
@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. -
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.