QTcpSocket state always connected
-
@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?
-
@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.
@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 fileLIBS += -lws2_32Next 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; } } -
@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 fileLIBS += -lws2_32Next 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; } }@puzzled_giraffe
QTcpsocket have not got "connectState" setup? I think qt use long tcp connection by default.