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. QTcpSocket state always connected
QtWS25 Last Chance

QTcpSocket state always connected

Scheduled Pinned Locked Moved Unsolved General and Desktop
qtcpsocketclient
23 Posts 7 Posters 17.1k 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.
  • Gianluca86G Offline
    Gianluca86G Offline
    Gianluca86
    wrote on last edited by
    #1

    Hi,
    I have a problem with the status of the tcp socket. If the server disconnects or I unplug the ethernet cable, the status remains "Connected".
    Do I have to set something beyond the normal creation of the socket?
    Does the KeepAliveOption have something to do with it?

    Thanks

    raven-worxR 2 Replies Last reply
    0
    • Gianluca86G Gianluca86

      Hi,
      I have a problem with the status of the tcp socket. If the server disconnects or I unplug the ethernet cable, the status remains "Connected".
      Do I have to set something beyond the normal creation of the socket?
      Does the KeepAliveOption have something to do with it?

      Thanks

      raven-worxR Offline
      raven-worxR Offline
      raven-worx
      Moderators
      wrote on last edited by
      #2

      @Gianluca86
      a little bit more of information would be helpful.
      What OS, Qt version, etc.

      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
      If you have a question please use the forum so others can benefit from the solution in the future

      1 Reply Last reply
      0
      • Gianluca86G Offline
        Gianluca86G Offline
        Gianluca86
        wrote on last edited by
        #3

        I'm using Qt 5.5 on Ubuntu 32 Bit.
        Unfortunately I can't upgrade to 64 Bit and 5.9.
        This a little example

        // Open
        m_pTcpSocket = new QTcpSocket();
        m_pTcpSocket->connectToHost(strIP,uiPort);
        if(!m_pTcpSocket->waitForConnected(lTimeout))
        {// Error
           Close();
        }
        
        // Check
        if (m_pTcpSocket->state() == QAbstractSocket::ConnectedState)
        {
           return bConnected;
        }
        
        raven-worxR 1 Reply Last reply
        0
        • Gianluca86G Gianluca86

          I'm using Qt 5.5 on Ubuntu 32 Bit.
          Unfortunately I can't upgrade to 64 Bit and 5.9.
          This a little example

          // Open
          m_pTcpSocket = new QTcpSocket();
          m_pTcpSocket->connectToHost(strIP,uiPort);
          if(!m_pTcpSocket->waitForConnected(lTimeout))
          {// Error
             Close();
          }
          
          // Check
          if (m_pTcpSocket->state() == QAbstractSocket::ConnectedState)
          {
             return bConnected;
          }
          
          raven-worxR Offline
          raven-worxR Offline
          raven-worx
          Moderators
          wrote on last edited by
          #4

          @Gianluca86
          and how are you checking if you stay connected?
          I mean the condition which leads you to "stays always connected".

          --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
          If you have a question please use the forum so others can benefit from the solution in the future

          1 Reply Last reply
          0
          • Gianluca86G Offline
            Gianluca86G Offline
            Gianluca86
            wrote on last edited by
            #5

            Sorry, I forgot the else:

            // Check
            if (m_pTcpSocket->state() == QAbstractSocket::ConnectedState)
            {
               return bConnected;
            }
            else
            {// Do other stuff
            }
            

            and I insert before the If

            qDebug()<<m_pTcpSocket->state();
            
            1 Reply Last reply
            0
            • VRoninV Offline
              VRoninV Offline
              VRonin
              wrote on last edited by
              #6

              add QObject::connect(m_pTcpSocket,&QAbstractSocket::disconnected,[]()->void{qDebug("Disconnected");});

              and see if it prints the disconnection message

              "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
              ~Napoleon Bonaparte

              On a crusade to banish setIndexWidget() from the holy land of Qt

              1 Reply Last reply
              2
              • Gianluca86G Gianluca86

                Hi,
                I have a problem with the status of the tcp socket. If the server disconnects or I unplug the ethernet cable, the status remains "Connected".
                Do I have to set something beyond the normal creation of the socket?
                Does the KeepAliveOption have something to do with it?

                Thanks

                raven-worxR Offline
                raven-worxR Offline
                raven-worx
                Moderators
                wrote on last edited by raven-worx
                #7

                @Gianluca86 said in QTcpSocket state always connected:

                If the server disconnects or I unplug the ethernet cable, the status remains "Connected".

                i still don't see any code where you would (dynamically) react on such event?!
                Or where do you assume in your code that to happen?

                --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                If you have a question please use the forum so others can benefit from the solution in the future

                1 Reply Last reply
                2
                • Gianluca86G Offline
                  Gianluca86G Offline
                  Gianluca86
                  wrote on last edited by
                  #8

                  @raven-worx :
                  I didn't write all the code, however I always call the function that contains the check if, what I wrote before.

                  @VRonin :
                  I can't, I have a error.

                  raven-worxR VRoninV 2 Replies Last reply
                  0
                  • Gianluca86G Gianluca86

                    @raven-worx :
                    I didn't write all the code, however I always call the function that contains the check if, what I wrote before.

                    @VRonin :
                    I can't, I have a error.

                    raven-worxR Offline
                    raven-worxR Offline
                    raven-worx
                    Moderators
                    wrote on last edited by
                    #9

                    @Gianluca86 said in QTcpSocket state always connected:

                    @raven-worx :
                    I didn't write all the code, however I always call the function that contains the check if, what I wrote before.

                    @VRonin :
                    I can't, I have a error.

                    Do you really expect help with such horrible replies?
                    You simply hide code, you just say you have an error, but dont even tell with one .... seriously?

                    --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                    If you have a question please use the forum so others can benefit from the solution in the future

                    1 Reply Last reply
                    1
                    • Gianluca86G Gianluca86

                      @raven-worx :
                      I didn't write all the code, however I always call the function that contains the check if, what I wrote before.

                      @VRonin :
                      I can't, I have a error.

                      VRoninV Offline
                      VRoninV Offline
                      VRonin
                      wrote on last edited by
                      #10

                      @Gianluca86 said in QTcpSocket state always connected:

                      I can't, I have a error.

                      What kind of error?

                      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                      ~Napoleon Bonaparte

                      On a crusade to banish setIndexWidget() from the holy land of Qt

                      1 Reply Last reply
                      0
                      • Gianluca86G Offline
                        Gianluca86G Offline
                        Gianluca86
                        wrote on last edited by
                        #11

                        @raven-worx :
                        The error does not depend on my code.
                        It is simply the Socket that returns the Connected state.
                        As I said, I call the IF, nothing else. There is no other code I need to show.

                        @VRonin :
                        warning: lambda expressions only available with -std=c++11 or -std=gnu++11 [enabled by default]
                        QObject::connect(m_pTcpSocket,&QAbstractSocket::disconnected,->void{qDebug("Disconnected");});
                        ^

                        VRoninV 1 Reply Last reply
                        0
                        • Gianluca86G Gianluca86

                          @raven-worx :
                          The error does not depend on my code.
                          It is simply the Socket that returns the Connected state.
                          As I said, I call the IF, nothing else. There is no other code I need to show.

                          @VRonin :
                          warning: lambda expressions only available with -std=c++11 or -std=gnu++11 [enabled by default]
                          QObject::connect(m_pTcpSocket,&QAbstractSocket::disconnected,->void{qDebug("Disconnected");});
                          ^

                          VRoninV Offline
                          VRoninV Offline
                          VRonin
                          wrote on last edited by VRonin
                          #12

                          @Gianluca86 said in QTcpSocket state always connected:

                          lambda expressions only available with -std=c++11 or -std=gnu++11 [enabled by default]

                          add CONFIG += c++11 to your .pro file and re-run qmake to fix this or just create a Q_SLOT void logDisconnect(){qDebug("Disconnected");} and connect to that instead of the lambda

                          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                          ~Napoleon Bonaparte

                          On a crusade to banish setIndexWidget() from the holy land of Qt

                          1 Reply Last reply
                          3
                          • Gianluca86G Offline
                            Gianluca86G Offline
                            Gianluca86
                            wrote on last edited by
                            #13

                            It prints the disconnection message. But the state doesn't change.
                            I think I'll give up, I'll use the Send and Receive timeout to check the connection. Thanks for the help.

                            raven-worxR VRoninV 2 Replies Last reply
                            0
                            • Gianluca86G Gianluca86

                              It prints the disconnection message. But the state doesn't change.
                              I think I'll give up, I'll use the Send and Receive timeout to check the connection. Thanks for the help.

                              raven-worxR Offline
                              raven-worxR Offline
                              raven-worx
                              Moderators
                              wrote on last edited by
                              #14

                              @Gianluca86 said in QTcpSocket state always connected:

                              It prints the disconnection message. But the state doesn't change.

                              Since you said you do not need to post more code, i tell you it's impossible to achieve what you want with the code you've posted so far.
                              I also do not know how you are checking the state. Obviously the code you've posted only checks the state once. And thats right after a connection happened...

                              So what do you actually expect?

                              --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                              If you have a question please use the forum so others can benefit from the solution in the future

                              1 Reply Last reply
                              2
                              • Gianluca86G Offline
                                Gianluca86G Offline
                                Gianluca86
                                wrote on last edited by
                                #15

                                After the connection, I call the function with the check state every 3 seconds, with a timer.
                                I don't do anything special, I simply create a Socket, connect and check state, nothing more.
                                So I would expect that if the server program to which I was connected closes, the state of my tcpsocket changes, but unfortunately it doesn't happen, so I'll have to use another method to know if the connection is active.

                                thanks anyway

                                1 Reply Last reply
                                0
                                • Gianluca86G Gianluca86

                                  It prints the disconnection message. But the state doesn't change.
                                  I think I'll give up, I'll use the Send and Receive timeout to check the connection. Thanks for the help.

                                  VRoninV Offline
                                  VRoninV Offline
                                  VRonin
                                  wrote on last edited by
                                  #16

                                  @Gianluca86 said in QTcpSocket state always connected:

                                  But the state doesn't change.

                                  Pretty sure it does https://code.woboq.org/qt5/qtbase/src/network/socket/qabstractsocket.cpp.html#2788

                                  In fact you can connect to stateChanged signal to check that

                                  "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                                  ~Napoleon Bonaparte

                                  On a crusade to banish setIndexWidget() from the holy land of Qt

                                  1 Reply Last reply
                                  0
                                  • puzzled_giraffeP Offline
                                    puzzled_giraffeP Offline
                                    puzzled_giraffe
                                    wrote on last edited by puzzled_giraffe
                                    #17

                                    Hi everyone.
                                    Topic is old, but problem still exists. I'm using QT 5.14.1 on Windows 7 and tried to compile project with MinGW(32/64) and MSVC17(32/64), but results are same: socket does not react on physical disconnect.
                                    It is important remark that I can't use blocking calls (like waitForBytesWritten() / waitForConnected() / etc) in my project.

                                    First I used next check (I think TS talked about something like this):

                                    bool IsConnected() {
                                         return socket_.state() == QTcpSocket::ConnectedState;
                                    }
                                    //---- somewhere in code -----
                                    if(IsConnected()) {
                                       // do something;
                                    } else { /*error occured*/ }
                                    

                                    And I got same result: if wire was plugged out after connection state still was ::ConnectedState. Next I tried to use socket signals:

                                        connect(&socket_, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(sockStateChanged(QAbstractSocket::SocketState)));
                                        connect(&socket_, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(sockErrorOccured(QAbstractSocket::SocketError)));
                                    

                                    sockStateChanged() and sockErrorOccured() only send messages to debug output with text from error list and states.
                                    They work fine during connection saying what is happening with socket:

                                    // if wire is plugged in
                                    State changed:  "The socket is performing a host name lookup."
                                    State changed:  "The socket has started establishing a connection."
                                    State changed:  "connection is established."
                                    // if not
                                    State changed:  "The socket is performing a host name lookup."
                                    State changed:  "The socket has started establishing a connection."
                                    State changed:  "The socket is not connected."
                                    Socket error occured:  "An error occurred with the network (e.g., the network cable was accidentally plugged out)."
                                    

                                    But when connection established they just stop working. If I plug out wire no signals would be emitted and state would not change (still ConnectedState). Even if I try to send something, there is no reaction (see UPD). If I plug wire back nothing happens (board/server will not receive/send data, no signals emitted).
                                    I tried to use VRonin method too, but it does not work (no disconnected() signal).

                                    QObject::connect(&socket_, &QAbstractSocket::disconnected, []()->void{qDebug("Disconnected");});
                                    

                                    After all only one solution seems to work for me: use timer to wait response and disconnect if there is nothing to read.

                                    // timer as class member
                                    QTimer readTimer;
                                    int readTimeout;
                                    //-----------------------
                                    void configureTimer() 
                                    {
                                        // configuring & connection to slot readReply()
                                        readTimer.setSingleShot(true);
                                        readTimer.setInterval(readTimeout);
                                        connect(&readTimer, SIGNAL(timeout()), this, SLOT(readReply()));
                                    }
                                    //-----------------------
                                    void sendRequest()
                                    {
                                        if (socket_.write(pingRequest_) == -1) {
                                            // result is always 0 after connection, so we would not get here
                                            qDebug() << "Request: sending failed";
                                            return;
                                        }
                                        // timer will call readReply after waiting
                                        readTimer.start();
                                    }
                                    //-----------------------
                                    void readReply()
                                    {
                                        if (socket_.bytesAvailable() == 0 || !isConnected()) {
                                           qDebug() << "No bytes available or disconnected");
                                           // call reconnect
                                           return;
                                        }
                                      
                                         QByteArray reply = socket_.readAll();
                                         //do something with reply
                                    }
                                    

                                    UPD:
                                    I found out that if you try to send data when wire is out after a ~20 sec timeout socket will close emitting all necessary signals.
                                    But it will stay Connected if you don't. I waited for several minutes and state was not changed.

                                    So you should send "ping" sometimes to know about disconnect in case if your application doesn't send data often. If your ping waits reply you can close socket by timeout, if not - wait for automatic closing.

                                    how did I get here?

                                    KroMignonK 1 Reply Last reply
                                    0
                                    • puzzled_giraffeP puzzled_giraffe

                                      Hi everyone.
                                      Topic is old, but problem still exists. I'm using QT 5.14.1 on Windows 7 and tried to compile project with MinGW(32/64) and MSVC17(32/64), but results are same: socket does not react on physical disconnect.
                                      It is important remark that I can't use blocking calls (like waitForBytesWritten() / waitForConnected() / etc) in my project.

                                      First I used next check (I think TS talked about something like this):

                                      bool IsConnected() {
                                           return socket_.state() == QTcpSocket::ConnectedState;
                                      }
                                      //---- somewhere in code -----
                                      if(IsConnected()) {
                                         // do something;
                                      } else { /*error occured*/ }
                                      

                                      And I got same result: if wire was plugged out after connection state still was ::ConnectedState. Next I tried to use socket signals:

                                          connect(&socket_, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(sockStateChanged(QAbstractSocket::SocketState)));
                                          connect(&socket_, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(sockErrorOccured(QAbstractSocket::SocketError)));
                                      

                                      sockStateChanged() and sockErrorOccured() only send messages to debug output with text from error list and states.
                                      They work fine during connection saying what is happening with socket:

                                      // if wire is plugged in
                                      State changed:  "The socket is performing a host name lookup."
                                      State changed:  "The socket has started establishing a connection."
                                      State changed:  "connection is established."
                                      // if not
                                      State changed:  "The socket is performing a host name lookup."
                                      State changed:  "The socket has started establishing a connection."
                                      State changed:  "The socket is not connected."
                                      Socket error occured:  "An error occurred with the network (e.g., the network cable was accidentally plugged out)."
                                      

                                      But when connection established they just stop working. If I plug out wire no signals would be emitted and state would not change (still ConnectedState). Even if I try to send something, there is no reaction (see UPD). If I plug wire back nothing happens (board/server will not receive/send data, no signals emitted).
                                      I tried to use VRonin method too, but it does not work (no disconnected() signal).

                                      QObject::connect(&socket_, &QAbstractSocket::disconnected, []()->void{qDebug("Disconnected");});
                                      

                                      After all only one solution seems to work for me: use timer to wait response and disconnect if there is nothing to read.

                                      // timer as class member
                                      QTimer readTimer;
                                      int readTimeout;
                                      //-----------------------
                                      void configureTimer() 
                                      {
                                          // configuring & connection to slot readReply()
                                          readTimer.setSingleShot(true);
                                          readTimer.setInterval(readTimeout);
                                          connect(&readTimer, SIGNAL(timeout()), this, SLOT(readReply()));
                                      }
                                      //-----------------------
                                      void sendRequest()
                                      {
                                          if (socket_.write(pingRequest_) == -1) {
                                              // result is always 0 after connection, so we would not get here
                                              qDebug() << "Request: sending failed";
                                              return;
                                          }
                                          // timer will call readReply after waiting
                                          readTimer.start();
                                      }
                                      //-----------------------
                                      void readReply()
                                      {
                                          if (socket_.bytesAvailable() == 0 || !isConnected()) {
                                             qDebug() << "No bytes available or disconnected");
                                             // call reconnect
                                             return;
                                          }
                                        
                                           QByteArray reply = socket_.readAll();
                                           //do something with reply
                                      }
                                      

                                      UPD:
                                      I found out that if you try to send data when wire is out after a ~20 sec timeout socket will close emitting all necessary signals.
                                      But it will stay Connected if you don't. I waited for several minutes and state was not changed.

                                      So you should send "ping" sometimes to know about disconnect in case if your application doesn't send data often. If your ping waits reply you can close socket by timeout, if not - wait for automatic closing.

                                      KroMignonK Offline
                                      KroMignonK Offline
                                      KroMignon
                                      wrote on last edited by
                                      #18

                                      @puzzled_giraffe If you want your TCP socket to fast detect connection with counterpart is lost, you have to set KeepAliveOption. On Windows systems, you have to do this before connecting the socket.

                                          auto mySocket = new QTcpSocket();
                                          mySocket->setSocketOption(QAbstractSocket::KeepAliveOption, 1);
                                          mySocket->connectToHost(...);
                                      

                                      It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                                      puzzled_giraffeP 1 Reply Last reply
                                      2
                                      • KroMignonK KroMignon

                                        @puzzled_giraffe If you want your TCP socket to fast detect connection with counterpart is lost, you have to set KeepAliveOption. On Windows systems, you have to do this before connecting the socket.

                                            auto mySocket = new QTcpSocket();
                                            mySocket->setSocketOption(QAbstractSocket::KeepAliveOption, 1);
                                            mySocket->connectToHost(...);
                                        
                                        puzzled_giraffeP Offline
                                        puzzled_giraffeP Offline
                                        puzzled_giraffe
                                        wrote on last edited by puzzled_giraffe
                                        #19

                                        @KroMignon I googled it a bit and found that this option only enables "keep alive" mode on socket. Windows has a 2 hours default delay before first request, so it is not very useful if someone wants to get actual connection state.
                                        So we return to "heartbit ping", OS registry changing (to reduce default intervals) or low level socket configuring.

                                        I tried it in a code, so yes, it does not have an noticable effect without additional actions.

                                        how did I get here?

                                        KroMignonK 1 Reply Last reply
                                        0
                                        • puzzled_giraffeP puzzled_giraffe

                                          @KroMignon I googled it a bit and found that this option only enables "keep alive" mode on socket. Windows has a 2 hours default delay before first request, so it is not very useful if someone wants to get actual connection state.
                                          So we return to "heartbit ping", OS registry changing (to reduce default intervals) or low level socket configuring.

                                          I tried it in a code, so yes, it does not have an noticable effect without additional actions.

                                          KroMignonK Offline
                                          KroMignonK Offline
                                          KroMignon
                                          wrote on last edited by
                                          #20

                                          @puzzled_giraffe said in QTcpSocket state always connected:

                                          I tried it in a code, so yes, it does not have an effect without additional actions.

                                          By googling in found this:

                                          The SO_KEEPALIVE socket option is valid only for protocols that support the notion of keep-alive (connection-oriented protocols). For TCP, the default keep-alive timeout is 2 hours and the keep-alive interval is 1 second. The default number of keep-alive probes varies based on the version of Windows.

                                          So for Windows, you can setup those settings like this:

                                          int fd = mySocket->socketDescriptor();
                                          int enableKeepAlive = 1;
                                          int maxIdle = 10;
                                          int count = 3;
                                          int interval = 2;
                                          int result;
                                          
                                          result = setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &enableKeepAlive, sizeof(enableKeepAlive));
                                          result = setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &maxIdle, sizeof(maxIdle));
                                          result = setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &count, sizeof(count));
                                          result = setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &interval, sizeof(interval));
                                          

                                          Take a look at https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-setsockopt for more details.

                                          It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                                          puzzled_giraffeP 1 Reply Last reply
                                          1

                                          • Login

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