QTcpSocket Write
-
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.
-
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. -
Can I use QTimer in MyThread Class?
cannot create children for a parent that is in a different thread -> this error occurred. -
Is there any way?
-
-
@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. -
Threads are not needed here at all. Also where do you create your 'socket' ?
-
@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").
-
@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
-
@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