Solved QTcpClient, stops at connectToHost ?
-
I have one application that is listening:
if ( !listen(QHostAddress::Any, muint16Port) ) {
muint16Port is a member, unsigned, integer of type quint16 containing 8123. Another application tries to connect using an instance of QTcpSocket, the instance of QTcpSocket is created using:
mpsckClient(new QTcpSocket(pParent))
The signal / slot connections:
QObject::connect(mpsckClient, &QAbstractSocket::errorOccurred ,this, &clsMsgSender::onErrorOccurred); QObject::connect(mpsckClient, &QIODevice::readyRead ,this, &clsMsgSender::onDataIn);
Here is the connection code:
mpsckClient->abort(); //Connect to the Application /*mpsckClient->setProxy(QNetworkProxy::NoProxy);*/ // <- Not required mpsckClient->connectToHost(crstrHost, cint16Port);
I call abort before hand just incase there is already an existing connection. However when I run this within Qt Creator the debugger halts on the line connectToHost.
crstrHost is a constant reference to an instance of QString it contains the local IP address of my system 192.168.1.158, cint16Port is a constant Integer of type qint16 containing 8123.
Why is Qt Creator stopping on this line, there is no reason given that I can see, what haven't I done?
Is there anything I can add to the code before the call to connectToHost that would give me a clue as to why it cannot connect?
Build Issues:
warning: Project WARNING: Qt has only been tested with version 10.15 of the platform SDK, you're using 11.1. warning: Project WARNING: This is an unsupported configuration. You may experience build issues, and by using warning: Project WARNING: the 11.1 SDK you are opting in to new features that Qt has not been prepared for. warning: Project WARNING: Please downgrade the SDK you use to build your app to version 10.15, or configure warning: Project WARNING: with CONFIG+=sdk_no_version_check when running qmake to silence this warning.
I've built and looked at the fortuneclient and I cannot see any differences, yet it connects to my application fine.
I followed the advice and added:
CONFIG += sdk_no_version_check
No build issues now.
-
In my hunt I found the problem and fixed, I have a slot called onTryToConnect, here is the signal connection:
QObject::connect(this, &clsMsgSender::tryToConnect ,this, &clsMsgSender::onTryToConnect, Qt::DirectConnection);
tryToConnect is a signal emitted by my class on first cycle of the thread loop.
while( mblnRun == true ) { //Sleep to allow a small cap between transmission QThread::usleep(100); quint16 uint16Port = uint16GetPort(); sckCurState = eGetSockState(); if ( eLastState != sckCurState ) { eLastState = sckCurState; if ( !(eLastState == QAbstractSocket::ConnectedState || eLastState == QAbstractSocket::ConnectingState) ) { emit tryToConnect(QHostInfo::localHostName(), uint16Port); } } if ( eLastState != QAbstractSocket::ConnectedState ) { continue; }
The problem is that the tryToConnect signal was being emitted more than once, the original slot wasn't written to handle this, so I've re-written it now to:
void clsMsgSender::onTryToConnect(const QString& crstrHost, const quint16 cint16Port) { #if defined(DEBUG_SOCKETS) qdbg() << "Connecting to: " << crstrHost << ":" << cint16Port; #endif QMutexLocker lock(&mMutex); if ( mpsckClient == nullptr ) { QObject* pParent(parent()); mpsckClient = new QTcpSocket(pParent); QObject::connect(mpsckClient, &QAbstractSocket::connected ,this, &clsMsgSender::onConnected); QObject::connect(mpsckClient, &QAbstractSocket::errorOccurred ,this, &clsMsgSender::onErrorOccurred); QObject::connect(mpsckClient, &QAbstractSocket::hostFound ,this, &clsMsgSender::onHostFound); QObject::connect(mpsckClient, &QIODevice::readyRead ,this, &clsMsgSender::onDataIn); } QAbstractSocket::SocketState sckState = mpsckClient->state(); if ( sckState == QAbstractSocket::ConnectedState || sckState == QAbstractSocket::ConnectingState ) { return; } if ( sckState != QAbstractSocket::UnconnectedState ) { //Just in cast they're is a previous connection attempt mpsckClient->abort(); } //Connect to the Application mpsckClient->connectToHost(crstrHost, cint16Port); }
Now it works!
-
This post is deleted! -
If I replace the IP address in crstrHost with the name of the host, the connection state changes to HostLookupState and is stuck there. Why doesn't the IP address work?
-
Wrong IP but correct hostname?!
The socket is opened in the given openMode and first enters HostLookupState, then performs a host name lookup of hostName. If the lookup succeeds, hostFound() is emitted and QAbstractSocket enters ConnectingState
(https://doc.qt.io/qt-5/qabstractsocket.html#connectToHost)
What do
hostFound()
anderrorOccurred()
say? (when using the IP) -
@Pl45m4 , thanks for the response, it's not quite work, whilst its different now the state is stuck in HostLookupState.
-
@Pl45m4 said in QTcpClient, stops at connectToHost ?:
hostFound
I do connect to hostFound, although my slot never gets called. I already connect to errorOccurred, no errors or my slot isn't being called either.
-
The socket is opened in the given openMode and first enters HostLookupState, then performs a host name lookup of hostName. If the lookup succeeds, hostFound() is emitted
How long does it stay in
HostLookupState
? Forever?I guess your hostname can't be resolved into your IP address. Could be a misconfiguration of your DNS / Gateway.
Does the lookup work at all? (Something like
ping
ornslookup
HOSTNAME
) -
@Pl45m4 , I left it quite a while, it doesn't seem to change state. I've run up fortuneclient and this works, as far as I can see it looks like I'm repeating exactly the same, in fortuneclient I past in the host name where as in my code it uses the function:
QHostInfo::localHostName()
Which I've checked the host it returns and it is correct.
-
I have a feeling it is something to do with how the QTcpSocket is created and the parent. The debugger gets stuck on connectToHost this is without a breakpoint, it doesn't show any warning or message, is there anyway to get more help on why the debugger is halting at this location?
-
Today, in the same application I added:
QTcpSocket* pTest = new QTcpSocket(); QObject::connect(pTest, &QAbstractSocket::connected ,this, []() { qdbg() << "connected"; }); QObject::connect(pTest, &QAbstractSocket::errorOccurred ,this, []() { qdbg() << "errorOccurred"; }); QObject::connect(pTest, &QAbstractSocket::hostFound ,this, []() { qdbg() << "host found"; }); pTest->abort(); pTest->connectToHost("www.google.com", 80); pTest->waitForConnected(5000);
I put a break point after the waitForConnected call. It works fine, and in the Application Output I see:
2021-01-17 13:29:27.229164+0000 mdFileIO[1155:15681] host found 2021-01-17 13:29:27.466221+0000 mdFileIO[1155:15681] connected
So I'm now trying to resolve what's different and why my existing call to connectToHost isn't working, yet if I open the fortuneclient and change the host and port to match my application that works too.
-
In my hunt I found the problem and fixed, I have a slot called onTryToConnect, here is the signal connection:
QObject::connect(this, &clsMsgSender::tryToConnect ,this, &clsMsgSender::onTryToConnect, Qt::DirectConnection);
tryToConnect is a signal emitted by my class on first cycle of the thread loop.
while( mblnRun == true ) { //Sleep to allow a small cap between transmission QThread::usleep(100); quint16 uint16Port = uint16GetPort(); sckCurState = eGetSockState(); if ( eLastState != sckCurState ) { eLastState = sckCurState; if ( !(eLastState == QAbstractSocket::ConnectedState || eLastState == QAbstractSocket::ConnectingState) ) { emit tryToConnect(QHostInfo::localHostName(), uint16Port); } } if ( eLastState != QAbstractSocket::ConnectedState ) { continue; }
The problem is that the tryToConnect signal was being emitted more than once, the original slot wasn't written to handle this, so I've re-written it now to:
void clsMsgSender::onTryToConnect(const QString& crstrHost, const quint16 cint16Port) { #if defined(DEBUG_SOCKETS) qdbg() << "Connecting to: " << crstrHost << ":" << cint16Port; #endif QMutexLocker lock(&mMutex); if ( mpsckClient == nullptr ) { QObject* pParent(parent()); mpsckClient = new QTcpSocket(pParent); QObject::connect(mpsckClient, &QAbstractSocket::connected ,this, &clsMsgSender::onConnected); QObject::connect(mpsckClient, &QAbstractSocket::errorOccurred ,this, &clsMsgSender::onErrorOccurred); QObject::connect(mpsckClient, &QAbstractSocket::hostFound ,this, &clsMsgSender::onHostFound); QObject::connect(mpsckClient, &QIODevice::readyRead ,this, &clsMsgSender::onDataIn); } QAbstractSocket::SocketState sckState = mpsckClient->state(); if ( sckState == QAbstractSocket::ConnectedState || sckState == QAbstractSocket::ConnectingState ) { return; } if ( sckState != QAbstractSocket::UnconnectedState ) { //Just in cast they're is a previous connection attempt mpsckClient->abort(); } //Connect to the Application mpsckClient->connectToHost(crstrHost, cint16Port); }
Now it works!