QTcpSocket, execution halts why and what does it mean?
-
I'm trying to write a client that connects to an another application, I'm using QTcpSocket, I've written a thread to connect to the application, here is the thread body of the class:
void clsMsgSender::run() { //Default last state to connected as it won't be! QAbstractSocket::SocketState eCurState, eLastState; QString strHost(QHostInfo::localHostName()); quint16 uint16Port(uint16GetPort()); QTcpSocket sckClient; #if defined(DEBUG_SOCKETS) QObject::connect(&sckClient, &QAbstractSocket::connected ,this, &clsMsgSender::onConnected); QObject::connect(&sckClient, &QAbstractSocket::errorOccurred ,this, &clsMsgSender::onErrorOccurred); QObject::connect(&sckClient, &QAbstractSocket::hostFound ,this, &clsMsgSender::onHostFound); #endif mMutex.lock(); mpsckClient = &sckClient; mMutex.unlock(); while( mblnRun == true ) { //Sleep to allow a small cap between transmission QThread::usleep(100); eCurState = sckClient.state(); if ( eLastState != eCurState || eCurState == QAbstractSocket::UnconnectedState ) { eLastState = eCurState; if ( eCurState == QAbstractSocket::ConnectedState ) { #if defined(DEBUG_SOCKETS) qdbg() << "Connected!"; #endif } else if ( eCurState == QAbstractSocket::UnconnectedState ) { sckClient.connectToHost(strHost, uint16Port); if (!sckClient.waitForConnected(clsMsgSender::mscuint16ConnectionTO)) { #if defined(DEBUG_SOCKETS) qdbg() << "Couldn't connect to: " << mstrHost << ":" << muint16Port; #endif break; } } }
Part of it...When I run this in the debugger (Qt Creator) and no server application is running that is listening for the connect, the execution halts on the line:
if (!sckClient.waitForConnected(clsMsgSender::mscuint16ConnectionTO)) {
A yellow arrow to the left of the line number indicates the execution has halted. There is no breakpoint on this line, so why is it stopping there and what does it mean?
Is there anyway to get more information on why Qt Creator is halting there?
-
I'm trying to write a client that connects to an another application, I'm using QTcpSocket, I've written a thread to connect to the application, here is the thread body of the class:
void clsMsgSender::run() { //Default last state to connected as it won't be! QAbstractSocket::SocketState eCurState, eLastState; QString strHost(QHostInfo::localHostName()); quint16 uint16Port(uint16GetPort()); QTcpSocket sckClient; #if defined(DEBUG_SOCKETS) QObject::connect(&sckClient, &QAbstractSocket::connected ,this, &clsMsgSender::onConnected); QObject::connect(&sckClient, &QAbstractSocket::errorOccurred ,this, &clsMsgSender::onErrorOccurred); QObject::connect(&sckClient, &QAbstractSocket::hostFound ,this, &clsMsgSender::onHostFound); #endif mMutex.lock(); mpsckClient = &sckClient; mMutex.unlock(); while( mblnRun == true ) { //Sleep to allow a small cap between transmission QThread::usleep(100); eCurState = sckClient.state(); if ( eLastState != eCurState || eCurState == QAbstractSocket::UnconnectedState ) { eLastState = eCurState; if ( eCurState == QAbstractSocket::ConnectedState ) { #if defined(DEBUG_SOCKETS) qdbg() << "Connected!"; #endif } else if ( eCurState == QAbstractSocket::UnconnectedState ) { sckClient.connectToHost(strHost, uint16Port); if (!sckClient.waitForConnected(clsMsgSender::mscuint16ConnectionTO)) { #if defined(DEBUG_SOCKETS) qdbg() << "Couldn't connect to: " << mstrHost << ":" << muint16Port; #endif break; } } }
Part of it...When I run this in the debugger (Qt Creator) and no server application is running that is listening for the connect, the execution halts on the line:
if (!sckClient.waitForConnected(clsMsgSender::mscuint16ConnectionTO)) {
A yellow arrow to the left of the line number indicates the execution has halted. There is no breakpoint on this line, so why is it stopping there and what does it mean?
Is there anyway to get more information on why Qt Creator is halting there?
@SPlatten QTcpSocket is asynchronous, as many Qt classes, and needs therefore a working (not locked) event queue to work properly.
The while loop in your code is locking the event queue access, so this can NOT work.EDIT: by the way, what is clsMsgSender base class? I hope it is not QThread!
-
@SPlatten QTcpSocket is asynchronous, as many Qt classes, and needs therefore a working (not locked) event queue to work properly.
The while loop in your code is locking the event queue access, so this can NOT work.EDIT: by the way, what is clsMsgSender base class? I hope it is not QThread!
@KroMignon , thank you, it was following numerous online posts on how to use QTcpSocket. If this isn't the correct way to do it, then why are there so many posts out there illustrating it? I will try replacing this with the signal/slot alternative.
Why do you hope that clsMsgSender isn't a class? Yes it is a thread.
-
@KroMignon , thank you, it was following numerous online posts on how to use QTcpSocket. If this isn't the correct way to do it, then why are there so many posts out there illustrating it? I will try replacing this with the signal/slot alternative.
Why do you hope that clsMsgSender isn't a class? Yes it is a thread.
@SPlatten said in QTcpSocket, execution halts why and what does it mean?:
If this isn't the correct way to do it, then why are there so many posts out there illustrating it?
Hmm, I have never found a working example using QTcpSocket which is looking the event loop.
Can you share some links? -
@SPlatten said in QTcpSocket, execution halts why and what does it mean?:
If this isn't the correct way to do it, then why are there so many posts out there illustrating it?
Hmm, I have never found a working example using QTcpSocket which is looking the event loop.
Can you share some links?@KroMignon , do you mean isn't ?
Links:
https://doc.qt.io/qt-5/qabstractsocket.html#waitForConnected
https://www.bogotobogo.com/Qt/Qt5_QTcpSocket.phpThere are many more.
-
@KroMignon , do you mean isn't ?
Links:
https://doc.qt.io/qt-5/qabstractsocket.html#waitForConnected
https://www.bogotobogo.com/Qt/Qt5_QTcpSocket.phpThere are many more.
@SPlatten I don't see any event loop blocking loops in the links you posted. Your "while( mblnRun == true )" blocks the event loop. If you want to use Qt properly don't block the event loop - one of the most basic rules when using event driven frameworks.
-
@SPlatten I don't see any event loop blocking loops in the links you posted. Your "while( mblnRun == true )" blocks the event loop. If you want to use Qt properly don't block the event loop - one of the most basic rules when using event driven frameworks.
-
@SPlatten said in QTcpSocket, execution halts why and what does it mean?:
can you please help me with an example?
Yes, but an example for doing what exactly?
@KroMignon , the examples I've found on QThread do not include how to NOT block the event loop, so an example on what to do in the thread so it doesn't block the event loop.
I've just added:
QCoreApplication::processEvents();
To the thread loops, is this enough?
-
@KroMignon , do you mean isn't ?
Links:
https://doc.qt.io/qt-5/qabstractsocket.html#waitForConnected
https://www.bogotobogo.com/Qt/Qt5_QTcpSocket.phpThere are many more.
In general you can say that
for(;;){}
while(1)
while(true)
<- this is what you are doing basically
are pure evil, when used together with Qt GUI Framework. There might be some exceptions (esp. plain C++ code) but it's not safe to use it, when having signals&slots + events in use.
In your linked example this
if (socket->waitForConnected(1000))
for example, wont block the event loop forever, if this is what you were thinking.
-
In general you can say that
for(;;){}
while(1)
while(true)
<- this is what you are doing basically
are pure evil, when used together with Qt GUI Framework. There might be some exceptions (esp. plain C++ code) but it's not safe to use it, when having signals&slots + events in use.
In your linked example this
if (socket->waitForConnected(1000))
for example, wont block the event loop forever, if this is what you were thinking.
-
@KroMignon , the examples I've found on QThread do not include how to NOT block the event loop, so an example on what to do in the thread so it doesn't block the event loop.
I've just added:
QCoreApplication::processEvents();
To the thread loops, is this enough?
@SPlatten said in QTcpSocket, execution halts why and what does it mean?:
To the thread loops, is this enough?
I am not sure, is
clsMsgSender
aQThread
or aQObject
?@SPlatten I will try to share with you how I use QTcpSocket.
First, there is no need to create a thread for that, the easiest implementation is (for me):
// supposing mSocket is a member of the current class mSocket = new QTcpSocket(); // remove TCP delay mSocket->setSocketOption(QAbstractSocket::LowDelayOption, 1); QObject::connect(mSocket, &QAbstractSocket::connected, [this]() { qDebug() << "Connected with" << mSocket->peerPort(); // Do stuff here }); QObject::connect(mSocket, &QAbstractSocket::disconnected, [this]() { qDebug() << "Disconnected from" << mSocket->peerPort(); mSocket->delateLater(); mSocket = nullptr; }); QObject::connect(mSocket, &QIODevice::bytesWritten, [this](qint64 bytes) { qDebug() << bytes << "send to " << mSocket->peerPort(); // do stuff (add next data?) }); mSocket->connectToHost(remoteIp, tcpPort); QObject::connect(mSocket, &QIODevice::readyRead, [this](){ auto buffer = mSocket->readAll(); qDebug() << "receiving" << buffer.size() << "bytes from" << mSocket->peerPort(); // do stuff with data });
-
@KroMignon , the examples I've found on QThread do not include how to NOT block the event loop, so an example on what to do in the thread so it doesn't block the event loop.
I've just added:
QCoreApplication::processEvents();
To the thread loops, is this enough?
@SPlatten said in QTcpSocket, execution halts why and what does it mean?:
the examples I've found on QThread do not include how to NOT block the event loop
Here, this wont block:
- https://www.bogotobogo.com/Qt/Qt5_QTcpSocket.php (your 2nd linked example)
This guy (https://stackoverflow.com/questions/37167927/proper-way-to-run-managable-background-thread-with-qthread) has made a similar mistake.
You want to connect once and then let the event loop and your signals do the rest. -
Funny - this discussion was already done more than 3 months ago already: https://forum.qt.io/topic/120700/receiving-data-from-qtcpsocket/30
-
Funny - this discussion was already done more than 3 months ago already: https://forum.qt.io/topic/120700/receiving-data-from-qtcpsocket/30
@Christian-Ehrlicher , is it any surprise I'm confused, in that thread you pointed me to the Fortune client and server examples, which I have been following then there is conflicting advice that comes back form this forum when I implement a solution that I'm having problems with.
Add to this the what appears to be flaky Qt Creator with updates that seem to send me backwards. I feel I'm loosing the plot.
-
The old thread told you to use signals and slots and not the waitFor functions and now we're at the exactly same place.
-
The old thread told you to use signals and slots and not the waitFor functions and now we're at the exactly same place.
@Christian-Ehrlicher , well obviously I have mental memory issues.
-
The old thread told you to use signals and slots and not the waitFor functions and now we're at the exactly same place.
@Christian-Ehrlicher , the examples that ship with Qt 5.15.2 include:
blockingfortuneclient
threadedfortuneserverOn looking at both, these are the sources I used to base my work on. My server is slightly different in that the clients are intended to stay connected after establishing a connection.
I will compare the client source with my own.
-
From my pov you don't need threads at all but this is not what you want to hear for whatever reason - you rather work on simple stuff like a QTcpSocket for months.
-
From my pov you don't need threads at all but this is not what you want to hear for whatever reason - you rather work on simple stuff like a QTcpSocket for months.
@Christian-Ehrlicher , one day I will be ready to share what I'm working on, which isn't now.