QT TCP Socket | Send more than one command
-
wrote on 13 Jul 2020, 09:59 last edited by
Hi guys!
I am on Windows using QT Creator4.12.4 + QT 5.15
For a small Home Project I have a power supply module, where I can send commands over TCP to enable voltage, set current, get serial number and so on
I wanted to write a small test application(console based) to set the voltage etc..
My problem is to send one command, wait for response from the module(i get the same sent command back) and after that i want to send another command.
I am a beginner in QT and now googling for 2 days and couldn find a soultion, I hope you guys can help me out. This is my code now:#include <QCoreApplication> #include <QtNetwork> #include <QAbstractSocket> #include <iostream> #include <tcpsever.h> #include <sockettest.h> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); sockettest mTest; mTest.ConnectSocket(); while (mTest.isConnected) { mTest.writeToPsu(); } return a.exec(); }
Header for tcp client:
#ifndef SOCKETTEST_H #define SOCKETTEST_H #include <QObject> #include <QTcpSocket> #include <QAbstractSocket> class sockettest : public QObject { Q_OBJECT public: explicit sockettest(QObject *parent = nullptr); void ConnectSocket(); void writeToPsu(); bool isConnected; signals: public slots: void connected(); void disconnected(); void bytesWritten(qint64 bytes); void readyRead(); private: QTcpSocket *socket; }; #endif // SOCKETTEST_H
Implementation File for connection+disconnect+method for writing to PSU
#include "sockettest.h" #include <iostream> sockettest::sockettest(QObject *parent) : QObject(parent) { } void sockettest::ConnectSocket() { socket = new QTcpSocket(this); connect(socket, SIGNAL(connected()), this, SLOT(connected())); connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected())); connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead())); connect(socket, SIGNAL(bytesWritten(qint64)), this, SLOT(bytesWritten(qint64))); qDebug()<<"Connecting..."; socket->connectToHost("192.168.0.198",44440); //socket->waitForConnected(1000); if(!socket->waitForConnected(5000)){ isConnected=false; qDebug()<<"Error: "<<socket->errorString(); } } void sockettest::writeToPsu() { qDebug()<<"Is connected: "<<isConnected; QTextStream qtin(stdin); QString command; qDebug()<<"Enter command:"; qtin>>command; socket->write(command.toUtf8()); socket->waitForBytesWritten(); } void sockettest::connected() { qDebug() << "Connected!"; isConnected=true; //writeToPsu(); /*QTextStream qtin(stdin); QString command; qDebug()<<"Enter command:"; qtin>>command; socket->write(command.toUtf8());*/ //Commands for PSU //Voltage: OUT[x]:VOLTAGE:XXXX -> xxxx in mV //Current: OUT[x]:CURRENT:XXXX -> in mA //socket->write("OUT1:CURRENT:500"); //Get Identification of PSU //socket->write("*IDN?"); //Get Serial Number of PSU //socket->write("*SERIAL?"); //Get SW Version of PSU //socket->write("*SW?"); } void sockettest::disconnected() { qDebug() << "Disconnected!"; isConnected=false; } void sockettest::bytesWritten(qint64 bytes) { qDebug() << "We wrote: " << bytes; } void sockettest::readyRead() { QByteArray array; qDebug() << "Reading..."; while (socket->bytesAvailable()) { array+=socket->readAll(); } qDebug() << array; qDebug()<<"Reading finished!"; }
Sorry for such a big post like this, I hope you can help me out! :)
Thanks in advance! -
Hi guys!
I am on Windows using QT Creator4.12.4 + QT 5.15
For a small Home Project I have a power supply module, where I can send commands over TCP to enable voltage, set current, get serial number and so on
I wanted to write a small test application(console based) to set the voltage etc..
My problem is to send one command, wait for response from the module(i get the same sent command back) and after that i want to send another command.
I am a beginner in QT and now googling for 2 days and couldn find a soultion, I hope you guys can help me out. This is my code now:#include <QCoreApplication> #include <QtNetwork> #include <QAbstractSocket> #include <iostream> #include <tcpsever.h> #include <sockettest.h> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); sockettest mTest; mTest.ConnectSocket(); while (mTest.isConnected) { mTest.writeToPsu(); } return a.exec(); }
Header for tcp client:
#ifndef SOCKETTEST_H #define SOCKETTEST_H #include <QObject> #include <QTcpSocket> #include <QAbstractSocket> class sockettest : public QObject { Q_OBJECT public: explicit sockettest(QObject *parent = nullptr); void ConnectSocket(); void writeToPsu(); bool isConnected; signals: public slots: void connected(); void disconnected(); void bytesWritten(qint64 bytes); void readyRead(); private: QTcpSocket *socket; }; #endif // SOCKETTEST_H
Implementation File for connection+disconnect+method for writing to PSU
#include "sockettest.h" #include <iostream> sockettest::sockettest(QObject *parent) : QObject(parent) { } void sockettest::ConnectSocket() { socket = new QTcpSocket(this); connect(socket, SIGNAL(connected()), this, SLOT(connected())); connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected())); connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead())); connect(socket, SIGNAL(bytesWritten(qint64)), this, SLOT(bytesWritten(qint64))); qDebug()<<"Connecting..."; socket->connectToHost("192.168.0.198",44440); //socket->waitForConnected(1000); if(!socket->waitForConnected(5000)){ isConnected=false; qDebug()<<"Error: "<<socket->errorString(); } } void sockettest::writeToPsu() { qDebug()<<"Is connected: "<<isConnected; QTextStream qtin(stdin); QString command; qDebug()<<"Enter command:"; qtin>>command; socket->write(command.toUtf8()); socket->waitForBytesWritten(); } void sockettest::connected() { qDebug() << "Connected!"; isConnected=true; //writeToPsu(); /*QTextStream qtin(stdin); QString command; qDebug()<<"Enter command:"; qtin>>command; socket->write(command.toUtf8());*/ //Commands for PSU //Voltage: OUT[x]:VOLTAGE:XXXX -> xxxx in mV //Current: OUT[x]:CURRENT:XXXX -> in mA //socket->write("OUT1:CURRENT:500"); //Get Identification of PSU //socket->write("*IDN?"); //Get Serial Number of PSU //socket->write("*SERIAL?"); //Get SW Version of PSU //socket->write("*SW?"); } void sockettest::disconnected() { qDebug() << "Disconnected!"; isConnected=false; } void sockettest::bytesWritten(qint64 bytes) { qDebug() << "We wrote: " << bytes; } void sockettest::readyRead() { QByteArray array; qDebug() << "Reading..."; while (socket->bytesAvailable()) { array+=socket->readAll(); } qDebug() << array; qDebug()<<"Reading finished!"; }
Sorry for such a big post like this, I hope you can help me out! :)
Thanks in advance!hi @GCE_ and welcome
remove this while loop
while (mTest.isConnected) {
mTest.writeToPsu();
}it's blocking the event loop.
Even worse in your case, as it blocksa.exec();
from being called -> no event loop at all.The rest is ok for a first draft, but for production code, do not mix signal slots ( connect(aaa..., bbbb, cccc,dddd)) and waitForXXX calls
Stick with one, preferably with signal and slots.
Gave you an upvote so you can answer more frequently than once per 5 minutes :D
-
hi @GCE_ and welcome
remove this while loop
while (mTest.isConnected) {
mTest.writeToPsu();
}it's blocking the event loop.
Even worse in your case, as it blocksa.exec();
from being called -> no event loop at all.The rest is ok for a first draft, but for production code, do not mix signal slots ( connect(aaa..., bbbb, cccc,dddd)) and waitForXXX calls
Stick with one, preferably with signal and slots.
Gave you an upvote so you can answer more frequently than once per 5 minutes :D
wrote on 13 Jul 2020, 10:55 last edited by@J-Hilk
Thank you!
I removed the while loop now
I have the function writeToPsu()
Where in your opinion should I use this function?
And what exactly do you mean that I shouldn't mix signals and slots? -
@J-Hilk
Thank you!
I removed the while loop now
I have the function writeToPsu()
Where in your opinion should I use this function?
And what exactly do you mean that I shouldn't mix signals and slots?And what exactly do you mean that I shouldn't mix signals and slots?
I said you shouldn't mix
signal/slots
withwaitForSomecondition()
calls, that is mixing synchronous with asynchronous apisYou can probably place it here
void sockettest::connected() { qDebug() << "Connected!"; isConnected=true; writeToPsu(); }
right after you get notified that your connection was successful
-
wrote on 13 Jul 2020, 11:05 last edited by GCE_
-
Okay I did that and I get this now:
After Reading finished (OUT1:VOLTAGE:0 is Response from the PSU Module) I want again to send a command to the module
This is for now my biggest problem how to implement it.
So I want to enter as many commands as I want until I close the terminal@GCE_
well, for start, you can simply addwriteToPsu();
after
qDebug()<<"Reading finished!";
That will continuously send your single command.
If you want to change what you send, I would suggest creating a list of commands to send, and simply increment the index each readyRead call.
That way you will send all commands one after the other until you reach the end of your list
-
wrote on 13 Jul 2020, 11:17 last edited by
Thank you!
I now call the writeToPsu() method after reading finished and now it works the way I want!
Thank you very much for this!
Still have so many things to learn in QT but I am liking it more and more :D
Thank you!
1/7