Solved Console application & QTcpSocket
-
@SPlatten said in Console application & QTcpSocket:
At a fixed frequency send a heartbeat message to a QTcpServer
Qtimer
"Call an derived body function do perform any other required activities" - call it, or is there problems doing so?
"I've just installed the Debug Symbols and I still can't step into QIODevice/write to see what's happening." - isn't this from your other thread and not relevant for this one? Please don't mix topics. To step into Qt code you have to install Qt source code and set the path to it in QtCreator. Debug symbols only help to get meaningful stack traces.
-
@SPlatten said in Console application & QTcpSocket:
in my console application what I want to achieve is the following:
- At a fixed frequency send a heartbeat message to a QTcpServer
- Call an derived body function do perform any other required activities
To complete the application done by @Bonnie :
int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QTcpSocket socket; QTimer heartBeat; heartBeat.setSingleShot(false); heartBeat.setInterval(5000); // 5 seconds QObject::connect(heartBeat, &QTimer::timeout, [&](){ QDataStream stream; qDebug() << "heartBeat"; stream.setDevice(&socket); stream.setVersion(QDataStream::Qt_5_14); stream << "heartBeat"; }; QObject::connect(&socket, &QTcpSocket::bytesWritten, [&](qint64 bytes){ qDebug() << bytes << "written"; }); QObject::connect(&socket, &QTcpSocket::connected, [&](){ QDataStream stream; qDebug() << "connected"; stream.setDevice(&socket); stream.setVersion(QDataStream::Qt_5_14); stream << "TEST"; heartBeat.start(); }); QObject::connect(&socket, &QTcpSocket::disconnected, [&]() { qDebug() << "Bye bye"; a.exit(); }; qDebug() << "connecting"; socket.connectToHost("localhost", 8123); return a.exec(); }
-
@Bonnie ,@jsulm ,@KroMignon , odd results now, I've modified the console app main to:
QCoreApplication a(intArgc, parystrArgv); QCoreApplication::setApplicationName(clsModFileIO::scpszTitle()); clsModFileIO obj(&a, intArgc, parystrArgv); return a.exec();
In the clsModFileIO constructor:
QObject::connect(this, SIGNAL(connected()), this, SLOT(onConnected())); QObject::connect(this, SIGNAL(connected()), this, SLOT(onSendModuleStartupMsg())); QObject::connect(this, SIGNAL(connected()), this, SLOT(onStartHeartbeat())); QObject::connect(this, SIGNAL(disconnected()), this, SLOT(onDisconnected())); QObject::connect(this, &QAbstractSocket::errorOccurred, this, &clsModHelper::onErrorOccurred); QObject::connect(this, &QIODevice::readyRead, this, &clsModHelper::onDataIn); QObject::connect(this, SIGNAL(bytesWritten(qint64)), this, SLOT(onBytesWritten(qint64)));
This class is derived from QTcpSocket. OnConnected is a pure virtual slot. I am getting a receipt in onDataIn, but the encoding looks messed up, I am sending on JSON in my messages, what I get back looks like Japanese:
笢浯摵汥∺≘䵌䵐䅍≽
-
@SPlatten said in Console application & QTcpSocket:
what I get back looks like Japanese
Can't comment on that as I don't know what you are sending back and what encoding you're using.
-
@jsulm, I haven't called any encoding methods, what is the default?
-
@SPlatten For QString you can find this information in the documentation: https://doc.qt.io/qt-5/qstring.html
-
@SPlatten said in Console application & QTcpSocket:
This class is derived from QTcpSocket. OnConnected is a pure virtual slot. I am getting a receipt in onDataIn, but the encoding looks messed up, I am sending on JSON in my messages, what I get back looks like Japanese:
笢浯摵汥∺≘䵌䵐䅍≽Again this depends how you have written data on socket and how you read them on the other side.
You should know that for Qt QString internally always stored in UTF-8, but when you send it "outside" you have to take care about which string format is to be used.Please show the JSON write to socket and JSON read from socket code.
-
@SPlatten
I remember you're sending a QByteArray ( from QJsonDocument::toJson() ) by QDataStream.
Do you also use QDataStream to read to a QByteArray inonDataIn
? -
@Bonnie , @jsulm , @KroMignon , this is my send function:
void clsModHelper::sendJSON(QJsonObject& objJSON) { if ( isOpen() != true ) { return; } //Associate this TCP socket with the output data stream QByteArray arybytMsg; QDataStream dsOut(&arybytMsg, QIODevice::WriteOnly); //dsOut.setDevice(this); dsOut.setVersion(clsJSON::mscintQtVersion); //Send message to data stream dsOut << QJsonDocument(objJSON).toJson(QJsonDocument::Compact); //Write message write(arybytMsg); }
And receiving:
void clsModFileIO::onDataIn() { QDataStream dsIn; dsIn.setDevice(this); dsIn.setVersion(clsJSON::mscintQtVersion); QString strRx; dsIn.startTransaction(); dsIn >> strRx; if ( strRx.isEmpty() != true ) { qdbg() << "onDataIn: " << strRx; } if ( dsIn.commitTransaction() == false ) { return; } }
clsModFileIO is derived from clsModHelper. clsJSON::mscintQtVersion is defined as:
const int clsJSON::mscintQtVersion = QDataStream::Qt_5_14;
-
@SPlatten
But you are sending aQJsonDocument::toJson()
which returns aQByteArray
and receiving aQString
? So.... -
@SPlatten as @JonB has already written
QJsonDocument::toJson()
returns aQByteArray
not asQString
.You have to send and read the same thing if you want it to work!
void clsModFileIO::onDataIn() { QDataStream dsIn; dsIn.setDevice(this); dsIn.setVersion(clsJSON::mscintQtVersion); QByteArray jsonArray; dsIn.startTransaction(); dsIn >> jsonArray; QJsonDocument doc; if ( jsonArray.isEmpty() != true ) { qdbg() << "onDataIn: " << jsonArray; doc = QJsonDocument::fromJson(jsonArray); } if ( dsIn.commitTransaction() == false ) { return; } }
[EDIT] This only works if you also change the send:
void clsModHelper::sendJSON(QJsonObject& objJSON) { if ( isOpen() != true ) { return; } //Associate this TCP socket with the output data stream QDataStream dsOut; dsOut.setDevice(this); dsOut.setVersion(clsJSON::mscintQtVersion); //Send message to data stream dsOut << QJsonDocument(objJSON).toJson(QJsonDocument::Compact); }
-
This post is deleted! -
@KroMignon , thank you, now its working!