Qt Message, what does it mean, is it important ?
-
@Christian-Ehrlicher Agree. I will be worried.
@Christian-Ehrlicher , @JoeCFD , not terribly helpful. These are added to the log file when the application is started, not as I originally said when it is terminated, there are just three that go into the log file, no more no less.
These are the classes mentioned in the reported messages, prototypes:
/** * File: clsListener.h * Notes: This file contains the prototypes for the classes: * clsServer and clsListener ******************************************************************************* * Class: clsServer * Inherits: QThread * * Members: * msckDescriptor Socket descriptor * mpsckIncoming Pointer to incoming socket * * Methods: * clsServer Class constructor * ~clsServer Class destructor * run Thread loop * * Signals: * error Signal emitted when error occurs * * Slots: * cleanup Cleanup socket * onDisconnected Slot connected to QAbstractSocket::disconnected * onErrorOccurred Slot connected to QAbstractSocket::errorOccurrred * onReadyRead Slot connected to QAbstractSocket::readyRead ******************************************************************************* * Class: clsListener * Inherits: QTcpServer * * Static Methods: * commonDecode Common JSON decode * pGetListener Access method to get listener for IP port * uint16NextPort Get next port * * Static Members: * msmpListeners Map of listeners * msuint16NextPort Next available port * * Members: * mpServer Pointer to instance of QTcpServer * muint16Port Port assigned to listener * * Methods: * clsListener Class constructor * ~clsListener Class destructor * uint16Port Access method to get port * * Slots: * onAcceptError Slot to accept socket error * onNewConnection Slot to accept new connection ******************************************************************************* * History: 2020/11/30 Created by Simon Platten */ #ifndef CLSLISTENER_H #define CLSLISTENER_H #include <map> #include <QAbstractSocket> #include <QDataStream> #include <QJsonDocument> #include <QJsonObject> #include <QQueue> #include <QTcpServer> #include <QTcpSocket> #include <QThread> class clsListener; typedef std::map<quint16, clsListener*> mpListeners; #if !defined(mqueJSON) typedef QQueue<QJsonObject> mqueJSON; #endif class clsServer : public QThread { Q_OBJECT private: qintptr msckDescriptor; QTcpSocket* mpsckIncoming; public: explicit clsServer(qintptr sckDescriptor, QObject* pParent = nullptr); ~clsServer(); void run(); signals: void error(QTcpSocket::SocketError socketerror); public slots: void cleanup(); void onDisconnected(); void onErrorOccurred(QAbstractSocket::SocketError error); void onReadyRead(); }; class clsListener : public QTcpServer { Q_OBJECT private: static mpListeners msmpListeners; static quint16 msuint16NextPort; quint16 muint16Port; public: clsListener(quint16 uint16Port, QObject* pParent = nullptr); ~clsListener(); //static void commonDecode(QAbstractSocket* psckIn); static clsListener* pGetListener(quint16 uint16Port); static quint16 uint16NextPort() { return ++clsListener::msuint16NextPort; } quint16 uint16Port() { return muint16Port; } signals: protected slots: void incomingConnection(qintptr sckDescriptor); }; #endif // CLSLISTENER_H
Implementations:
/** * File: clsListener.cpp * Notes: Contains implementation of the listener class * History: 2020/11/30 Created by Simon Platten * * To test, copy and paste the line below into a browser: * http://localhost:8123/?{"msgType":"ready","source":"simon"} */ #include <utility> #include "clsDebugService.h" #include "clsListener.h" #include "clsModule.h" /** * @brief clsServer::clsServer * @param sckDescriptor : Socket descriptor * @param pParent : Optional, pointer to parent */ clsServer::clsServer(qintptr sckDescriptor, QObject* pParent) : QThread(pParent) , msckDescriptor(sckDescriptor) , mpsckIncoming(nullptr) { //Register type for signals qRegisterMetaType<QAbstractSocket::SocketError>("QAbstractSocket::SocketError"); } /** * @brief clsServer::~clsServer */ clsServer::~clsServer() { if ( isRunning() == true ) { terminate(); while( isRunning() == true ) { //Wait until thread stops } } if ( mpsckIncoming != nullptr ) { cleanup(); } } /** * @brief clsServer::cleanup */ void clsServer::cleanup() { if ( mpsckIncoming != nullptr ) { QObject::disconnect(mpsckIncoming, &QAbstractSocket::errorOccurred ,this, &clsServer::onErrorOccurred); QObject::disconnect(mpsckIncoming, &QAbstractSocket::disconnected ,this, &clsServer::onDisconnected); QObject::disconnect(mpsckIncoming, &QAbstractSocket::readyRead ,this, &clsServer::onReadyRead); mpsckIncoming->deleteLater(); mpsckIncoming = nullptr; } } /** * @brief clsServer::onDisconnected */ void clsServer::onDisconnected() { qinf() << "Disconnected"; cleanup(); } /** * @brief clsServer::onErrorOccurred * @param error : error that occurred */ void clsServer::onErrorOccurred(QAbstractSocket::SocketError error) { //Display error QString strURLencoded(QUrl::toPercentEncoding(mpsckIncoming->errorString())); qwrn() << "Socket error(" << strURLencoded << ") https://www.google.com/search?rls=en&q=socket+error+code+" << strURLencoded << "&ie=UTF-8&oe=UTF-8" << strURLencoded << ".php"; //Prevent unused parameter warning (void)error; } /** * @brief clsServer::onReadyRead */ void clsServer::onReadyRead() { if ( mpsckIncoming == nullptr ) { return; } clsModule::manageReceivedData(mpsckIncoming); } /** * @brief clsServer::run */ void clsServer::run() { QTcpSocket* pSocket(new QTcpSocket()); //Set the ID if( !pSocket->setSocketDescriptor(msckDescriptor) ) { //Something's wrong, we just emit a signal emit error(pSocket->error()); return; } //Connect socket and signal pSocket->setSocketOption(QAbstractSocket::LowDelayOption, 1); mpsckIncoming = pSocket; QObject::connect(mpsckIncoming, &QAbstractSocket::errorOccurred ,this, &clsServer::onErrorOccurred); QObject::connect(mpsckIncoming, &QAbstractSocket::disconnected ,this, &clsServer::onDisconnected); QObject::connect(mpsckIncoming, &QAbstractSocket::readyRead ,this, &clsServer::onReadyRead); //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(); } //Static initialisation mpListeners clsListener::msmpListeners; quint16 clsListener::msuint16NextPort = 8122; //Will is increment before use /** * @brief clsListener class constructor * @param uint16Port : Port to listen on * @param pParent : Pointer to parent */ clsListener::clsListener(quint16 uint16Port, QObject* pParent) : QTcpServer(pParent), muint16Port(uint16Port) { if ( uint16Port == 0 ) { throw "Port invalid!"; } if ( clsListener::pGetListener(uint16Port) != nullptr ) { throw "Port already in use by another listener!"; } qinf() << QString("Listening to any local IP address on port: %1").arg(muint16Port); //Start listening to port if ( !listen(QHostAddress::Any, muint16Port) ) { qwrn() << "Unable to lisen to port " << muint16Port; } clsListener::msmpListeners.insert(std::make_pair(muint16Port, this)); } /** * @brief Removes listener */ clsListener::~clsListener() { if ( clsListener::msmpListeners.find(muint16Port) != clsListener::msmpListeners.end() ) { clsListener::msmpListeners.erase(muint16Port); } close(); } /** * @brief clsListener::incomingConnection * @param sckDescriptor : Socket descriptor for new connection */ void clsListener::incomingConnection(qintptr sckDescriptor) { //Every new connection will be run in a newly created thread clsServer* pThread(new clsServer(sckDescriptor, this)); //Look for module listening to this port // clsModule* pModule(pFindModuleListeningToPort(muint16Port)); //Connect signal/slot //Once a thread is not needed, it will be beleted later QObject::connect(pThread, &QThread::finished ,pThread, &QThread::deleteLater); pThread->start(); } /** * @brief clsListener::pGetListener * @param uint16Port : Port to search for listener using * @return Pointer to listener or nullptr if not found */ clsListener* clsListener::pGetListener(quint16 uint16Port) { mpListeners::iterator itrFound(clsListener::msmpListeners.find(uint16Port)); if ( itrFound != clsListener::msmpListeners.end() ) { return itrFound->second; } return nullptr; }
-
@Christian-Ehrlicher , @JoeCFD , not terribly helpful. These are added to the log file when the application is started, not as I originally said when it is terminated, there are just three that go into the log file, no more no less.
These are the classes mentioned in the reported messages, prototypes:
/** * File: clsListener.h * Notes: This file contains the prototypes for the classes: * clsServer and clsListener ******************************************************************************* * Class: clsServer * Inherits: QThread * * Members: * msckDescriptor Socket descriptor * mpsckIncoming Pointer to incoming socket * * Methods: * clsServer Class constructor * ~clsServer Class destructor * run Thread loop * * Signals: * error Signal emitted when error occurs * * Slots: * cleanup Cleanup socket * onDisconnected Slot connected to QAbstractSocket::disconnected * onErrorOccurred Slot connected to QAbstractSocket::errorOccurrred * onReadyRead Slot connected to QAbstractSocket::readyRead ******************************************************************************* * Class: clsListener * Inherits: QTcpServer * * Static Methods: * commonDecode Common JSON decode * pGetListener Access method to get listener for IP port * uint16NextPort Get next port * * Static Members: * msmpListeners Map of listeners * msuint16NextPort Next available port * * Members: * mpServer Pointer to instance of QTcpServer * muint16Port Port assigned to listener * * Methods: * clsListener Class constructor * ~clsListener Class destructor * uint16Port Access method to get port * * Slots: * onAcceptError Slot to accept socket error * onNewConnection Slot to accept new connection ******************************************************************************* * History: 2020/11/30 Created by Simon Platten */ #ifndef CLSLISTENER_H #define CLSLISTENER_H #include <map> #include <QAbstractSocket> #include <QDataStream> #include <QJsonDocument> #include <QJsonObject> #include <QQueue> #include <QTcpServer> #include <QTcpSocket> #include <QThread> class clsListener; typedef std::map<quint16, clsListener*> mpListeners; #if !defined(mqueJSON) typedef QQueue<QJsonObject> mqueJSON; #endif class clsServer : public QThread { Q_OBJECT private: qintptr msckDescriptor; QTcpSocket* mpsckIncoming; public: explicit clsServer(qintptr sckDescriptor, QObject* pParent = nullptr); ~clsServer(); void run(); signals: void error(QTcpSocket::SocketError socketerror); public slots: void cleanup(); void onDisconnected(); void onErrorOccurred(QAbstractSocket::SocketError error); void onReadyRead(); }; class clsListener : public QTcpServer { Q_OBJECT private: static mpListeners msmpListeners; static quint16 msuint16NextPort; quint16 muint16Port; public: clsListener(quint16 uint16Port, QObject* pParent = nullptr); ~clsListener(); //static void commonDecode(QAbstractSocket* psckIn); static clsListener* pGetListener(quint16 uint16Port); static quint16 uint16NextPort() { return ++clsListener::msuint16NextPort; } quint16 uint16Port() { return muint16Port; } signals: protected slots: void incomingConnection(qintptr sckDescriptor); }; #endif // CLSLISTENER_H
Implementations:
/** * File: clsListener.cpp * Notes: Contains implementation of the listener class * History: 2020/11/30 Created by Simon Platten * * To test, copy and paste the line below into a browser: * http://localhost:8123/?{"msgType":"ready","source":"simon"} */ #include <utility> #include "clsDebugService.h" #include "clsListener.h" #include "clsModule.h" /** * @brief clsServer::clsServer * @param sckDescriptor : Socket descriptor * @param pParent : Optional, pointer to parent */ clsServer::clsServer(qintptr sckDescriptor, QObject* pParent) : QThread(pParent) , msckDescriptor(sckDescriptor) , mpsckIncoming(nullptr) { //Register type for signals qRegisterMetaType<QAbstractSocket::SocketError>("QAbstractSocket::SocketError"); } /** * @brief clsServer::~clsServer */ clsServer::~clsServer() { if ( isRunning() == true ) { terminate(); while( isRunning() == true ) { //Wait until thread stops } } if ( mpsckIncoming != nullptr ) { cleanup(); } } /** * @brief clsServer::cleanup */ void clsServer::cleanup() { if ( mpsckIncoming != nullptr ) { QObject::disconnect(mpsckIncoming, &QAbstractSocket::errorOccurred ,this, &clsServer::onErrorOccurred); QObject::disconnect(mpsckIncoming, &QAbstractSocket::disconnected ,this, &clsServer::onDisconnected); QObject::disconnect(mpsckIncoming, &QAbstractSocket::readyRead ,this, &clsServer::onReadyRead); mpsckIncoming->deleteLater(); mpsckIncoming = nullptr; } } /** * @brief clsServer::onDisconnected */ void clsServer::onDisconnected() { qinf() << "Disconnected"; cleanup(); } /** * @brief clsServer::onErrorOccurred * @param error : error that occurred */ void clsServer::onErrorOccurred(QAbstractSocket::SocketError error) { //Display error QString strURLencoded(QUrl::toPercentEncoding(mpsckIncoming->errorString())); qwrn() << "Socket error(" << strURLencoded << ") https://www.google.com/search?rls=en&q=socket+error+code+" << strURLencoded << "&ie=UTF-8&oe=UTF-8" << strURLencoded << ".php"; //Prevent unused parameter warning (void)error; } /** * @brief clsServer::onReadyRead */ void clsServer::onReadyRead() { if ( mpsckIncoming == nullptr ) { return; } clsModule::manageReceivedData(mpsckIncoming); } /** * @brief clsServer::run */ void clsServer::run() { QTcpSocket* pSocket(new QTcpSocket()); //Set the ID if( !pSocket->setSocketDescriptor(msckDescriptor) ) { //Something's wrong, we just emit a signal emit error(pSocket->error()); return; } //Connect socket and signal pSocket->setSocketOption(QAbstractSocket::LowDelayOption, 1); mpsckIncoming = pSocket; QObject::connect(mpsckIncoming, &QAbstractSocket::errorOccurred ,this, &clsServer::onErrorOccurred); QObject::connect(mpsckIncoming, &QAbstractSocket::disconnected ,this, &clsServer::onDisconnected); QObject::connect(mpsckIncoming, &QAbstractSocket::readyRead ,this, &clsServer::onReadyRead); //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(); } //Static initialisation mpListeners clsListener::msmpListeners; quint16 clsListener::msuint16NextPort = 8122; //Will is increment before use /** * @brief clsListener class constructor * @param uint16Port : Port to listen on * @param pParent : Pointer to parent */ clsListener::clsListener(quint16 uint16Port, QObject* pParent) : QTcpServer(pParent), muint16Port(uint16Port) { if ( uint16Port == 0 ) { throw "Port invalid!"; } if ( clsListener::pGetListener(uint16Port) != nullptr ) { throw "Port already in use by another listener!"; } qinf() << QString("Listening to any local IP address on port: %1").arg(muint16Port); //Start listening to port if ( !listen(QHostAddress::Any, muint16Port) ) { qwrn() << "Unable to lisen to port " << muint16Port; } clsListener::msmpListeners.insert(std::make_pair(muint16Port, this)); } /** * @brief Removes listener */ clsListener::~clsListener() { if ( clsListener::msmpListeners.find(muint16Port) != clsListener::msmpListeners.end() ) { clsListener::msmpListeners.erase(muint16Port); } close(); } /** * @brief clsListener::incomingConnection * @param sckDescriptor : Socket descriptor for new connection */ void clsListener::incomingConnection(qintptr sckDescriptor) { //Every new connection will be run in a newly created thread clsServer* pThread(new clsServer(sckDescriptor, this)); //Look for module listening to this port // clsModule* pModule(pFindModuleListeningToPort(muint16Port)); //Connect signal/slot //Once a thread is not needed, it will be beleted later QObject::connect(pThread, &QThread::finished ,pThread, &QThread::deleteLater); pThread->start(); } /** * @brief clsListener::pGetListener * @param uint16Port : Port to search for listener using * @return Pointer to listener or nullptr if not found */ clsListener* clsListener::pGetListener(quint16 uint16Port) { mpListeners::iterator itrFound(clsListener::msmpListeners.find(uint16Port)); if ( itrFound != clsListener::msmpListeners.end() ) { return itrFound->second; } return nullptr; }
You're long enough here to know how to use a debugger and debug such warnings.. aren't you?
And searching for QT_FATAL_WARNINGS in the forum will reveal more help.QObject::connect(mpsckIncoming, &QAbstractSocket::errorOccurred ,this, &clsServer::onErrorOccurred);
And this was also discussed many times here - your slot is executed in the main thread and so QTcpSocket is accessed from the wrong thread. The forum search is something you should learn to use.
-
You're long enough here to know how to use a debugger and debug such warnings.. aren't you?
And searching for QT_FATAL_WARNINGS in the forum will reveal more help.QObject::connect(mpsckIncoming, &QAbstractSocket::errorOccurred ,this, &clsServer::onErrorOccurred);
And this was also discussed many times here - your slot is executed in the main thread and so QTcpSocket is accessed from the wrong thread. The forum search is something you should learn to use.
@Christian-Ehrlicher , Yes, thats exactly what I'm doing, just hoping someone might be able to suggest what could be wrong, apart from the logged message, everything seems to be working fine.
-
You're long enough here to know how to use a debugger and debug such warnings.. aren't you?
And searching for QT_FATAL_WARNINGS in the forum will reveal more help.QObject::connect(mpsckIncoming, &QAbstractSocket::errorOccurred ,this, &clsServer::onErrorOccurred);
And this was also discussed many times here - your slot is executed in the main thread and so QTcpSocket is accessed from the wrong thread. The forum search is something you should learn to use.
@Christian-Ehrlicher , if the error occurs in a thread, what is the correct way to manage this connection?
-
@Christian-Ehrlicher , if the error occurs in a thread, what is the correct way to manage this connection?
@SPlatten Do you even read my posts? I wrote what you did wrong (except that there is again no need for a thread and when using a thread reading the documentation on how to use it properly seems to be too hard)
-
@SPlatten Do you even read my posts? I wrote what you did wrong (except that there is again no need for a thread and when using a thread reading the documentation on how to use it properly seems to be too hard)
@Christian-Ehrlicher , maybe because your posts are very cryptic and its not easy to see what you are trying to say.
"except that there is again no need for a thread and when using a thread reading the documentation on how to use it properly seems to be too hard"
What does that even mean ?
-
@Christian-Ehrlicher , maybe because your posts are very cryptic and its not easy to see what you are trying to say.
"except that there is again no need for a thread and when using a thread reading the documentation on how to use it properly seems to be too hard"
What does that even mean ?
@SPlatten said in Qt Message, what does it mean, is it important ?:
What does that even mean ?
- you don't need a thread to read from a QTcpSocket but just use it because it's fancy without known what you're actually doing.
- you did not read the QThread documentation which clearly explains on how to properly use a QThread and don't care about it.
-
@SPlatten said in Qt Message, what does it mean, is it important ?:
What does that even mean ?
- you don't need a thread to read from a QTcpSocket but just use it because it's fancy without known what you're actually doing.
- you did not read the QThread documentation which clearly explains on how to properly use a QThread and don't care about it.
-
@SPlatten said in Qt Message, what does it mean, is it important ?:
What does that even mean ?
- you don't need a thread to read from a QTcpSocket but just use it because it's fancy without known what you're actually doing.
- you did not read the QThread documentation which clearly explains on how to properly use a QThread and don't care about it.
@Christian-Ehrlicher , Its actually not a problem at all, turns out the only time these messages are reported is when the application is terminated by clicking the stop button in Qt Creator.
If I close the application by clicking the close widgets on the window it doesn't exhibit the problem.
-
@Christian-Ehrlicher , Its actually not a problem at all, turns out the only time these messages are reported is when the application is terminated by clicking the stop button in Qt Creator.
If I close the application by clicking the close widgets on the window it doesn't exhibit the problem.
@Christian-Ehrlicher , I've tried various things in an attempt to figure out what you were suggesting, but I'm still seeing the same problem, can you be any more descriptive?
-
@Christian-Ehrlicher , I've tried various things in an attempt to figure out what you were suggesting, but I'm still seeing the same problem, can you be any more descriptive?
Do not do this.
class clsServer : public QThread { }
Instead, use a worker as Christian posted:
https://doc.qt.io/qt-6/qthread.html#details
It is critical.Another thing Christian pointed out is: why do you add QTcpSocket inside a thread?
What is the reason? -
@Christian-Ehrlicher , I've tried various things in an attempt to figure out what you were suggesting, but I'm still seeing the same problem, can you be any more descriptive?
@SPlatten
In Qt, the GUI elements (widgets) or QObject are not thread-safe, meaning they should
be created and manipulated only in the main thread. If you try to create or manipulate
GUI elements in a thread other than the main thread, you may encounter issues,
including the error message "Cannot create children for a parent that is in a different
thread." -
@SPlatten
In Qt, the GUI elements (widgets) or QObject are not thread-safe, meaning they should
be created and manipulated only in the main thread. If you try to create or manipulate
GUI elements in a thread other than the main thread, you may encounter issues,
including the error message "Cannot create children for a parent that is in a different
thread."