Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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?



  • @SPlatten

    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() and errorOccurred() 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.



  • @SPlatten

    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 or nslookup 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!


Log in to reply