Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Reconnecting using QAbstractSocket::connectToHost
Forum Updated to NodeBB v4.3 + New Features

Reconnecting using QAbstractSocket::connectToHost

Scheduled Pinned Locked Moved Solved General and Desktop
14 Posts 2 Posters 38.9k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • P Offline
    P Offline
    pingal
    wrote on last edited by pingal
    #3

    Thanks for the reply,
    So now my connections are as following:

    QObject::connect(&socket, &QAbstractSocket::disconnected, this, &Persistance_Connect::onDisconnected);
    QObject::connect(&socket, &QAbstractSocket::errorOccurred, this, &Persistance_Connect::onErr);
    

    Here is the onErr:

    void Persistance_Connect::onErr(QAbstractSocket::SocketError error)
    {
        qDebug() << "onErr is called";
    
        switch (error)
        {
        case QAbstractSocket::AddressInUseError:
            qDebug()<< "SOCKET ERROR: Address is already in use";
            break;
        case QAbstractSocket::ConnectionRefusedError:
            qDebug()<< "SOCKET ERROR: Connection refused";
            break;
        case QAbstractSocket::HostNotFoundError:
            qDebug()<< "SOCKET ERROR: Host not found";
            break;
        case QAbstractSocket::RemoteHostClosedError:
            qDebug()<< "SOCKET ERROR: Remote host closed";
            break;
        }
    
        socket.disconnectFromHost();
    }
    

    And here is my disconnect handler

    void Persistance_Connect::onDisconnected()
    {
        qDebug() << "Disconnected! Trying to Reconnect to "<<Server_Addr<<":"<<Server_ConnectionPort;
        socket.connectToHost(Server_Addr, Server_ConnectionPort, QIODevice::ReadWrite, QAbstractSocket::IPv4Protocol);
    }
    

    Still it doesn't reconnect. Here is the output when i tried to close connection from server after a succesfull connect

    Connected!
    Server_Addr:  "192.168.253.102"
    onErr is called
    SOCKET ERROR: Remote host closed
    Disconnected! Trying to Reconnect to  "192.168.253.102" : 7777
    
    JonBJ 1 Reply Last reply
    0
    • P pingal

      Thanks for the reply,
      So now my connections are as following:

      QObject::connect(&socket, &QAbstractSocket::disconnected, this, &Persistance_Connect::onDisconnected);
      QObject::connect(&socket, &QAbstractSocket::errorOccurred, this, &Persistance_Connect::onErr);
      

      Here is the onErr:

      void Persistance_Connect::onErr(QAbstractSocket::SocketError error)
      {
          qDebug() << "onErr is called";
      
          switch (error)
          {
          case QAbstractSocket::AddressInUseError:
              qDebug()<< "SOCKET ERROR: Address is already in use";
              break;
          case QAbstractSocket::ConnectionRefusedError:
              qDebug()<< "SOCKET ERROR: Connection refused";
              break;
          case QAbstractSocket::HostNotFoundError:
              qDebug()<< "SOCKET ERROR: Host not found";
              break;
          case QAbstractSocket::RemoteHostClosedError:
              qDebug()<< "SOCKET ERROR: Remote host closed";
              break;
          }
      
          socket.disconnectFromHost();
      }
      

      And here is my disconnect handler

      void Persistance_Connect::onDisconnected()
      {
          qDebug() << "Disconnected! Trying to Reconnect to "<<Server_Addr<<":"<<Server_ConnectionPort;
          socket.connectToHost(Server_Addr, Server_ConnectionPort, QIODevice::ReadWrite, QAbstractSocket::IPv4Protocol);
      }
      

      Still it doesn't reconnect. Here is the output when i tried to close connection from server after a succesfull connect

      Connected!
      Server_Addr:  "192.168.253.102"
      onErr is called
      SOCKET ERROR: Remote host closed
      Disconnected! Trying to Reconnect to  "192.168.253.102" : 7777
      
      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by JonB
      #4

      @pingal

      • How do we know for sure that whatever the server is it accepts reconnections? After the disconnectFromHost() in this application, try running e.g. a new instance of this application and verify that can connect first time?

      • Put a slot on void QAbstractSocket::stateChanged(QAbstractSocket::SocketState socketState) and monitor how the state is changing.

      • Not sure if it's relevant but try putting the disconnectFromHost() and/or the connectToHost() on a QTimer::singleShot() so that they do not happen while still inside a slot on the old connection, in case that makes any difference?

      • Temporarily try using a second, distinct QAbstractSocket socket2 (persistent, same place as wherever your current socket is declared) for the re-connect, just in case there is an issue on re-connecting the existing one?

      P 1 Reply Last reply
      0
      • JonBJ JonB

        @pingal

        • How do we know for sure that whatever the server is it accepts reconnections? After the disconnectFromHost() in this application, try running e.g. a new instance of this application and verify that can connect first time?

        • Put a slot on void QAbstractSocket::stateChanged(QAbstractSocket::SocketState socketState) and monitor how the state is changing.

        • Not sure if it's relevant but try putting the disconnectFromHost() and/or the connectToHost() on a QTimer::singleShot() so that they do not happen while still inside a slot on the old connection, in case that makes any difference?

        • Temporarily try using a second, distinct QAbstractSocket socket2 (persistent, same place as wherever your current socket is declared) for the re-connect, just in case there is an issue on re-connecting the existing one?

        P Offline
        P Offline
        pingal
        wrote on last edited by
        #5
        • How do we know for sure that whatever the server is it accepts reconnections? After the disconnectFromHost() in this application, try running e.g. a new instance of this application and verify that can connect first time?

        Yes, the server accepts reconnection and i've tried that using another instance.

        • Put a slot on void QAbstractSocket::stateChanged(QAbstractSocket::SocketState socketState) and monitor how the state is changing.

        Here is the output when the client is connected to the server

        QAbstractSocket::HostLookupState
        QAbstractSocket::ConnectingState
        QAbstractSocket::ConnectedState
        Connected!
        Server_Addr:  "192.168.253.102"
        

        And when the server closes the connection

        onErr is called
        SOCKET ERROR: Remote host closed
        QAbstractSocket::ClosingState
        QAbstractSocket::UnconnectedState
        Disconnected! Trying to Reconnect to  "192.168.253.102" : 7777
        QAbstractSocket::HostLookupState
        QAbstractSocket::ConnectingState
        
        • Not sure if it's relevant but try putting the disconnectFromHost() and/or the connectToHost() on a QTimer::singleShot() so that they do not happen while still inside a slot on the old connection, in case that makes any difference?

        Have not tried it yet

        • Temporarily try using a second, distinct QAbstractSocket socket2 (persistent, same place as wherever your current socket is declared) for the re-connect, just in case there is an issue on re-connecting the existing one?

        Have not tried it yet

        JonBJ 2 Replies Last reply
        0
        • P pingal
          • How do we know for sure that whatever the server is it accepts reconnections? After the disconnectFromHost() in this application, try running e.g. a new instance of this application and verify that can connect first time?

          Yes, the server accepts reconnection and i've tried that using another instance.

          • Put a slot on void QAbstractSocket::stateChanged(QAbstractSocket::SocketState socketState) and monitor how the state is changing.

          Here is the output when the client is connected to the server

          QAbstractSocket::HostLookupState
          QAbstractSocket::ConnectingState
          QAbstractSocket::ConnectedState
          Connected!
          Server_Addr:  "192.168.253.102"
          

          And when the server closes the connection

          onErr is called
          SOCKET ERROR: Remote host closed
          QAbstractSocket::ClosingState
          QAbstractSocket::UnconnectedState
          Disconnected! Trying to Reconnect to  "192.168.253.102" : 7777
          QAbstractSocket::HostLookupState
          QAbstractSocket::ConnectingState
          
          • Not sure if it's relevant but try putting the disconnectFromHost() and/or the connectToHost() on a QTimer::singleShot() so that they do not happen while still inside a slot on the old connection, in case that makes any difference?

          Have not tried it yet

          • Temporarily try using a second, distinct QAbstractSocket socket2 (persistent, same place as wherever your current socket is declared) for the re-connect, just in case there is an issue on re-connecting the existing one?

          Have not tried it yet

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by JonB
          #6

          @pingal said in Reconnecting using QAbstractSocket::connectToHost:

          QAbstractSocket::ConnectingState

          Looks to me like the client side is doing its bit but the server side is not accepting the reconnection, in a timely fashion. Do try those last 2 suggestions, especially the second one.

          Are you in charge of (have the code to) the server side, or is that third-party?

          P 1 Reply Last reply
          0
          • P pingal
            • How do we know for sure that whatever the server is it accepts reconnections? After the disconnectFromHost() in this application, try running e.g. a new instance of this application and verify that can connect first time?

            Yes, the server accepts reconnection and i've tried that using another instance.

            • Put a slot on void QAbstractSocket::stateChanged(QAbstractSocket::SocketState socketState) and monitor how the state is changing.

            Here is the output when the client is connected to the server

            QAbstractSocket::HostLookupState
            QAbstractSocket::ConnectingState
            QAbstractSocket::ConnectedState
            Connected!
            Server_Addr:  "192.168.253.102"
            

            And when the server closes the connection

            onErr is called
            SOCKET ERROR: Remote host closed
            QAbstractSocket::ClosingState
            QAbstractSocket::UnconnectedState
            Disconnected! Trying to Reconnect to  "192.168.253.102" : 7777
            QAbstractSocket::HostLookupState
            QAbstractSocket::ConnectingState
            
            • Not sure if it's relevant but try putting the disconnectFromHost() and/or the connectToHost() on a QTimer::singleShot() so that they do not happen while still inside a slot on the old connection, in case that makes any difference?

            Have not tried it yet

            • Temporarily try using a second, distinct QAbstractSocket socket2 (persistent, same place as wherever your current socket is declared) for the re-connect, just in case there is an issue on re-connecting the existing one?

            Have not tried it yet

            JonBJ Offline
            JonBJ Offline
            JonB
            wrote on last edited by JonB
            #7

            @pingal
            UPDATE
            Especially if you do find that a new socket2 does work: on your existing socket try calling bool QIODevice::reset() after disconnect before reconnect.

            And/or, read https://bugreports.qt.io/browse/QTBUG-18082?focusedCommentId=170619&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-170619, which seems to me to be your issue, re: my suggestion that after error there might be a problem. That is claiming

            The issue here is that connectToHost() is being called from within a slot connected to error() and that doesn't work, making ComEngine::connectToHost() into a slot and using QMetaObject::invokeMethod(this, "connectToHost", Qt::QueuedConnection); to have the reconnection attempt be made after works like a charm.

            "Bug" is over 10 years ago, but that doesn't stop it possibly still be applicable in QT... :) Read through https://stackoverflow.com/questions/11600288/qtcpsocket-client-auto-reconnect too.

            1 Reply Last reply
            0
            • JonBJ JonB

              @pingal said in Reconnecting using QAbstractSocket::connectToHost:

              QAbstractSocket::ConnectingState

              Looks to me like the client side is doing its bit but the server side is not accepting the reconnection, in a timely fashion. Do try those last 2 suggestions, especially the second one.

              Are you in charge of (have the code to) the server side, or is that third-party?

              P Offline
              P Offline
              pingal
              wrote on last edited by
              #8

              Looks to me like the client side is doing its bit but the server side is not accepting the reconnection

              I'm using a simple server i.e. netcat for debugging purposes and it works fine, I've even checked the signals from client to server in wireshark to verify that the client indeed is not requesting connection after disconnect, contrary to the QAbstractSocket::ConnectingState

              Untitled.png

              JonBJ 1 Reply Last reply
              0
              • P pingal

                Looks to me like the client side is doing its bit but the server side is not accepting the reconnection

                I'm using a simple server i.e. netcat for debugging purposes and it works fine, I've even checked the signals from client to server in wireshark to verify that the client indeed is not requesting connection after disconnect, contrary to the QAbstractSocket::ConnectingState

                Untitled.png

                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by JonB
                #9

                @pingal
                Point taken. Try the suggestions I have posted in previous 2 posts.

                Also i have just spotted what I thought in the docs for errorOccurred():

                When this signal is emitted, the socket may not be ready for a reconnect attempt. In that case, attempts to reconnect should be done from the event loop. For example, use a QTimer::singleShot() with 0 as the timeout.

                P 1 Reply Last reply
                0
                • JonBJ JonB

                  @pingal
                  Point taken. Try the suggestions I have posted in previous 2 posts.

                  Also i have just spotted what I thought in the docs for errorOccurred():

                  When this signal is emitted, the socket may not be ready for a reconnect attempt. In that case, attempts to reconnect should be done from the event loop. For example, use a QTimer::singleShot() with 0 as the timeout.

                  P Offline
                  P Offline
                  pingal
                  wrote on last edited by
                  #10

                  @JonB said in Reconnecting using QAbstractSocket::connectToHost:

                  @pingal
                  Point taken. Try the suggestions I have posted in previous 2 posts.

                  Also i have just spotted what I thought in the docs for errorOccurred():

                  When this signal is emitted, the socket may not be ready for a reconnect attempt. In that case, attempts to reconnect should be done from the event loop. For example, use a QTimer::singleShot() with 0 as the timeout.

                  using QTimer::singleShot like below:

                  void Persistance_Connect::onDisconnected()
                  {
                      qDebug() << "Disconnected! Trying to Reconnect to "<<Server_Addr<<":"<<Server_ConnectionPort;
                     QTimer::singleShot(0, this, SLOT(connect("192.168.253.102", 7777)));
                      socket.connectToHost(Server_Addr, Server_ConnectionPort, QIODevice::ReadWrite, QAbstractSocket::IPv4Protocol);
                  }
                  

                  output:

                  QMetaObject::invokeMethod: No such method Persistance_Connect::connect()
                  

                  I think I'm doing it wrong, kindly ignore my ignorance.

                  I've created socket2 for reconnection phase, same results.

                  JonBJ 1 Reply Last reply
                  0
                  • P pingal

                    @JonB said in Reconnecting using QAbstractSocket::connectToHost:

                    @pingal
                    Point taken. Try the suggestions I have posted in previous 2 posts.

                    Also i have just spotted what I thought in the docs for errorOccurred():

                    When this signal is emitted, the socket may not be ready for a reconnect attempt. In that case, attempts to reconnect should be done from the event loop. For example, use a QTimer::singleShot() with 0 as the timeout.

                    using QTimer::singleShot like below:

                    void Persistance_Connect::onDisconnected()
                    {
                        qDebug() << "Disconnected! Trying to Reconnect to "<<Server_Addr<<":"<<Server_ConnectionPort;
                       QTimer::singleShot(0, this, SLOT(connect("192.168.253.102", 7777)));
                        socket.connectToHost(Server_Addr, Server_ConnectionPort, QIODevice::ReadWrite, QAbstractSocket::IPv4Protocol);
                    }
                    

                    output:

                    QMetaObject::invokeMethod: No such method Persistance_Connect::connect()
                    

                    I think I'm doing it wrong, kindly ignore my ignorance.

                    I've created socket2 for reconnection phase, same results.

                    JonBJ Offline
                    JonBJ Offline
                    JonB
                    wrote on last edited by JonB
                    #11

                    @pingal said in Reconnecting using QAbstractSocket::connectToHost:

                    I've created socket2 for reconnection phase, same results.

                    That stumps me. If you can re-connect from a separate program but not from a brand new socket in the same program I don't know what to tell you. You can see from those links other people claimed to get it working.

                    The code you tried might better be, say:

                    // declare this method after `public slots:` in `.h` file
                    void Persistance_Connect::reconnect()
                    {
                        socket.connectToHost(Server_Addr, Server_ConnectionPort, QIODevice::ReadWrite, QAbstractSocket::IPv4Protocol);
                    }
                    
                    void Persistance_Connect::onDisconnected()
                    {
                        qDebug() << "Disconnected! Trying to Reconnect to "<<Server_Addr<<":"<<Server_ConnectionPort;
                        QTimer::singleShot(0, this, &Persistance_Connect::reconnect);
                    }
                    

                    but frankly if you cannot even get a fresh socket to reconnect I have little hope....

                    P 1 Reply Last reply
                    0
                    • JonBJ JonB

                      @pingal said in Reconnecting using QAbstractSocket::connectToHost:

                      I've created socket2 for reconnection phase, same results.

                      That stumps me. If you can re-connect from a separate program but not from a brand new socket in the same program I don't know what to tell you. You can see from those links other people claimed to get it working.

                      The code you tried might better be, say:

                      // declare this method after `public slots:` in `.h` file
                      void Persistance_Connect::reconnect()
                      {
                          socket.connectToHost(Server_Addr, Server_ConnectionPort, QIODevice::ReadWrite, QAbstractSocket::IPv4Protocol);
                      }
                      
                      void Persistance_Connect::onDisconnected()
                      {
                          qDebug() << "Disconnected! Trying to Reconnect to "<<Server_Addr<<":"<<Server_ConnectionPort;
                          QTimer::singleShot(0, this, &Persistance_Connect::reconnect);
                      }
                      

                      but frankly if you cannot even get a fresh socket to reconnect I have little hope....

                      P Offline
                      P Offline
                      pingal
                      wrote on last edited by
                      #12
                      This post is deleted!
                      1 Reply Last reply
                      0
                      • P Offline
                        P Offline
                        pingal
                        wrote on last edited by pingal
                        #13

                        So now i placed the reconnect in onErr like below

                        void Persistance_Connect::onErr(QAbstractSocket::SocketError error)
                        {
                            switch (error)
                            {
                            case QAbstractSocket::AddressInUseError:
                                qDebug()<< "SOCKET ERROR: Address is already in use";
                                break;
                            case QAbstractSocket::ConnectionRefusedError:
                                qDebug()<< "SOCKET ERROR: Connection refused";
                                break;
                            case QAbstractSocket::HostNotFoundError:
                                qDebug()<< "SOCKET ERROR: Host not found";
                                break;
                            case QAbstractSocket::RemoteHostClosedError:
                                qDebug()<< "SOCKET ERROR: Remote host closed";
                                break;
                            }
                            socket.disconnectFromHost();
                            QTimer::singleShot(0, this, &Persistance_Connect::reconnect); // Added here
                        }
                        

                        And removed the above from onDisconnect(). The module works fine now.

                        @JonB Thank you very much :)))

                        JonBJ 1 Reply Last reply
                        2
                        • P pingal

                          So now i placed the reconnect in onErr like below

                          void Persistance_Connect::onErr(QAbstractSocket::SocketError error)
                          {
                              switch (error)
                              {
                              case QAbstractSocket::AddressInUseError:
                                  qDebug()<< "SOCKET ERROR: Address is already in use";
                                  break;
                              case QAbstractSocket::ConnectionRefusedError:
                                  qDebug()<< "SOCKET ERROR: Connection refused";
                                  break;
                              case QAbstractSocket::HostNotFoundError:
                                  qDebug()<< "SOCKET ERROR: Host not found";
                                  break;
                              case QAbstractSocket::RemoteHostClosedError:
                                  qDebug()<< "SOCKET ERROR: Remote host closed";
                                  break;
                              }
                              socket.disconnectFromHost();
                              QTimer::singleShot(0, this, &Persistance_Connect::reconnect); // Added here
                          }
                          

                          And removed the above from onDisconnect(). The module works fine now.

                          @JonB Thank you very much :)))

                          JonBJ Offline
                          JonBJ Offline
                          JonB
                          wrote on last edited by JonB
                          #14

                          @pingal said in Reconnecting using QAbstractSocket::connectToHost:

                          The module works fine now.

                          Wow, that's great! (Still don't know why a socket2 did not work, but never mind.)

                          Like I suspected/wondered, the stackoverflow answers said that there is still some "clear up" which needs to be done after the disconnectFromHost() before a new connectToHost() will work on the socket, and that clear up needs to take place (somewhere/how) in the main event loop. Using a QTimer to delay, even with just a delay of 0, allows the main event loop to be re-entered to do its magic before it executes the reconnect.

                          BTW, note how I (always) use New Signal Slot Syntax for my connect()s, never the old style SIGNAL/SLOT() macros. This was actually introduced a long time ago at Qt5, but sadly many/most web examples still use the old syntax. The new one is much cleaner, and will pick up at compile-time whether the slot correctly matches the signal, instead of it failing (obscurely) at run-time. I suggest you always use the new style.

                          1 Reply Last reply
                          2

                          • Login

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • Users
                          • Groups
                          • Search
                          • Get Qt Extensions
                          • Unsolved