TCP client and QThread facing issue
-
wrote on 25 Feb 2019, 12:05 last edited by ManiRon
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.
wrote on 27 Feb 2019, 09:14 last edited by VRoninMyThread.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.wrote on 28 Feb 2019, 07:39 last edited byI 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 .
-
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 .
wrote on 28 Feb 2019, 08:04 last edited by@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.
8/10