Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-74118

SetSocketKeepAlive for QAbstractSocket

    XMLWordPrintable

Details

    • Suggestion
    • Resolution: Unresolved
    • P5: Not important
    • None
    • 5.11, 5.12.0, 5.13.0 Alpha 1
    • Network: Sockets
    • None
    • Windows

    Description

      Hi all,

      currently there is a little problem with QAbstractSocket which should be eliminated in the near future for a better stability.

      See: https://stackoverflow.com/questions/10445122/qtcpsocket-state-always-connected-even-unplugging-ethernet-wire

      In short: A opened socket will not detect, if a connection is unreachable / closed / disconnected. Afaik the OS (Windows) will do this after 2h. This duration is inacceptable.

      The sockets within the chromium engine have such an automatic detection.

      See: SetTCPKeepAlive within qtwebengine\src\3rdparty\chromium\net\socket\tcp_socket_win.cc

      and see: SetTCPKeepAlive within Qt\5.11.2\qtwebengine\src\3rdparty\chromium\net\socket\tcp_socket_posix.cc

       

      A Qt based implementation would look like this:

      // Includes for SetSocketKeepAlive
      #if defined _WINDOWS
       #include <winsock2.h>
       #include <Mstcpip.h>
      #else
       #include <sys/socket.h>
       #include <netinet/tcp.h>
      #endif
      
      
      /*!
       * \brief SetSocketKeepAlive
       * KeepAlive mechanism for sockets
       *
       * \param socket
       * \param enable
       * \param idletime
       * \param interval
       *
       * \return bool
       */
      bool GlobalServiceData::SetSocketKeepAlive(QAbstractSocket * socket, bool enable /*= true*/, unsigned idletime /*= 5*/, unsigned interval /*= 1*/)
      {
       int fd = socket->socketDescriptor();
      #if defined _WINDOWS
       // Adopted from: Qt\5.11.2\qtwebengine\src\3rdparty\chromium\net\socket\tcp_socket_win.cc 
      
       tcp_keepalive keepalive_vals = {
        enable ? 1u : 0u,  // TCP keep-alive on.
        idletime * 1000,  // Delay time before sending first TCP keep-alive packet.
        interval * 1000,  // Delay time between sending TCP keep-alive packets.
       };
       DWORD bytes_returned = 0xABAB;
       int rv = WSAIoctl(fd, SIO_KEEPALIVE_VALS, &keepalive_vals, sizeof(keepalive_vals), NULL, 0, &bytes_returned, NULL, NULL);
      
       // Disregard any failure in disabling nagle or enabling TCP Keep-Alive.
       return rv == 0;
      
      #else
      
       // Adopted from: Qt\5.11.2\qtwebengine\src\3rdparty\chromium\net\socket\tcp_socket_posix.cc
      
       // Enabling TCP keepalives is the same on all platforms.
       int on = enable ? 1 : 0;
       if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on))) { return false; }
      
       // If we disabled TCP keep alive, our work is done here.
       if (!enable) return true;
      
       // The following part only applies to OS_LINUX and OS_ANDROID
       // Setting the keepalive interval varies by platform.
       // Set seconds until first TCP keep alive.
       if (setsockopt(fd, SOL_TCP, TCP_KEEPIDLE, &idletime, sizeof(idletime))) { return false; }
      
       // Set seconds between TCP keep alives.
       if (setsockopt(fd, SOL_TCP, TCP_KEEPINTVL, &interval, sizeof(interval))) { return false; }
      
       return true;
      #endif
      }
      

      Would be nice to see this feature in an upcoming release of Qt implemented.

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            cnn Qt Core & Network
            lachrymology Mike
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There are no open Gerrit changes