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
Forum Updated to NodeBB v4.3 + New Features

QTcpSocket state always connected

Scheduled Pinned Locked Moved Unsolved General and Desktop
qtcpsocketclient
23 Posts 7 Posters 19.4k Views 2 Watching
  • 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.
  • JonBJ Offline
    JonBJ Offline
    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