Details
-
Suggestion
-
Resolution: Unresolved
-
P5: Not important
-
None
-
5.11, 5.12.0, 5.13.0 Alpha 1
-
None
Description
Hi all,
currently there is a little problem with QAbstractSocket which should be eliminated in the near future for a better stability.
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.