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 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
                                    • JonBJ Online
                                      JonBJ Online
                                      JonB
                                      wrote on last edited by JonB
                                      #21

                                      @puzzled_giraffe , @KroMignon
                                      I will just throw in an observation based on my tests years ago. Please take what I say with a pinch of salt, I might be wrong, @KroMignon may know more than I do, but....

                                      When I tried this out (under Windows) on a product we developed I actually found that the keep-alive stuff made the situation worse. Because it's testing all the time, I found that it actually noticed missing connections and dropped/closed them more than if I had nothing and left TCP to its own devices.

                                      So do you really need to be heartbeat pinging?

                                      1 Reply Last reply
                                      0
                                      • KroMignonK KroMignon

                                        @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.

                                        puzzled_giraffeP Offline
                                        puzzled_giraffeP Offline
                                        puzzled_giraffe
                                        wrote on last edited by puzzled_giraffe
                                        #22

                                        @KroMignon said in QTcpSocket state always connected:

                                        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));

                                        TCP_KEEPIDLE / TCP_KEEPCNT / TCP_KEEPINTVL - linux options, aren't they?

                                        So for windows I found next solution:
                                        add this lib to your project *.pro file

                                        LIBS += -lws2_32
                                        

                                        Next after socket connection you should use:

                                        #include <Ws2tcpip.h>
                                        //------
                                        // socket is QTcpSocket*
                                        if (socket->state() == QAbstractSocket::ConnectedState) {
                                            int fd = socket->socketDescriptor();    
                                            DWORD  dwBytesRet = 0;
                                            
                                            struct tcp_keepalive   alive;    // your options for "keepalive" mode    
                                            alive.onoff = TRUE;              // turn it on    
                                            alive.keepalivetime = 30000;     // delay (ms) between requests, here is 30s, default is 2h (7200000)    
                                            alive.keepaliveinterval = 5000;  // delay between "emergency" ping requests, their number (6) is not configurable
                                            /* So with this config  socket will send keepalive requests every 30 seconds after last data transaction when everything is ok.
                                               If there is no reply (wire plugged out) it'll send 6 requests with 5s delay  between them and then close. 
                                               As a result we will get disconnect after approximately 1 min timeout.
                                            */
                                            if (WSAIoctl(fd, SIO_KEEPALIVE_VALS, &alive, sizeof(alive), NULL, 0, &dwBytesRet, NULL, NULL) == SOCKET_ERROR) {    
                                                QDebug() << "WSAIotcl(SIO_KEEPALIVE_VALS) failed with err#" <<  WSAGetLastError();    
                                                return;    
                                            }
                                        }

                                        how did I get here?

                                        PangolinP 1 Reply Last reply
                                        0
                                        • puzzled_giraffeP puzzled_giraffe

                                          @KroMignon said in QTcpSocket state always connected:

                                          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));

                                          TCP_KEEPIDLE / TCP_KEEPCNT / TCP_KEEPINTVL - linux options, aren't they?

                                          So for windows I found next solution:
                                          add this lib to your project *.pro file

                                          LIBS += -lws2_32
                                          

                                          Next after socket connection you should use:

                                          #include <Ws2tcpip.h>
                                          //------
                                          // socket is QTcpSocket*
                                          if (socket->state() == QAbstractSocket::ConnectedState) {
                                              int fd = socket->socketDescriptor();    
                                              DWORD  dwBytesRet = 0;
                                              
                                              struct tcp_keepalive   alive;    // your options for "keepalive" mode    
                                              alive.onoff = TRUE;              // turn it on    
                                              alive.keepalivetime = 30000;     // delay (ms) between requests, here is 30s, default is 2h (7200000)    
                                              alive.keepaliveinterval = 5000;  // delay between "emergency" ping requests, their number (6) is not configurable
                                              /* So with this config  socket will send keepalive requests every 30 seconds after last data transaction when everything is ok.
                                                 If there is no reply (wire plugged out) it'll send 6 requests with 5s delay  between them and then close. 
                                                 As a result we will get disconnect after approximately 1 min timeout.
                                              */
                                              if (WSAIoctl(fd, SIO_KEEPALIVE_VALS, &alive, sizeof(alive), NULL, 0, &dwBytesRet, NULL, NULL) == SOCKET_ERROR) {    
                                                  QDebug() << "WSAIotcl(SIO_KEEPALIVE_VALS) failed with err#" <<  WSAGetLastError();    
                                                  return;    
                                              }
                                          }
                                          PangolinP Offline
                                          PangolinP Offline
                                          Pangolin
                                          wrote on last edited by
                                          #23

                                          @puzzled_giraffe
                                          QTcpsocket have not got "connectState" setup? I think qt use long tcp connection by default.

                                          Speak less and do more . You are your own worst enemy.

                                          1 Reply Last reply
                                          0

                                          • Login

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