[英]Socket keepalive not working
I have a client connect() to a server, and when idle, it times out after a couple hours. 我有一个客户端connect()到服务器,当空闲时,它会在几个小时后超时。 I added setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE...) with 1 sec but it didnt make a difference.
我在1秒内添加了setsockopt(套接字,SOL_SOCKET,SO_KEEPALIVE ...),但它并没有什么区别。 Any clues on why keepalive wouldnt work?
为什么keepalive不起作用的任何线索? Would it make a difference if I used SOL_TCP instead of SOL_SOCKET?
如果我使用SOL_TCP而不是SOL_SOCKET会有所不同吗? This is on Linux.
这是在Linux上。
int val = 1;
setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof val)
Just enables keepalives. 只需启用Keepalive。 You will get the default timers for keepalive probes, which you can view with the command:
您将获得keepalive探针的默认计时器,您可以使用以下命令查看:
sysctl net.ipv4.tcp_keepalive_time
Normally the default is couple of hours. 通常默认值是几个小时。
If you want to change the default timers, you could use this: 如果要更改默认计时器,可以使用:
struct KeepConfig cfg = { 60, 5, 5};
set_tcp_keepalive_cfg(fd, &cfg);
With the helper functions here: 这里有辅助函数:
struct KeepConfig {
/** The time (in seconds) the connection needs to remain
* idle before TCP starts sending keepalive probes (TCP_KEEPIDLE socket option)
*/
int keepidle;
/** The maximum number of keepalive probes TCP should
* send before dropping the connection. (TCP_KEEPCNT socket option)
*/
int keepcnt;
/** The time (in seconds) between individual keepalive probes.
* (TCP_KEEPINTVL socket option)
*/
int keepintvl;
};
/**
* enable TCP keepalive on the socket
* @param fd file descriptor
* @return 0 on success -1 on failure
*/
int set_tcp_keepalive(int sockfd)
{
int optval = 1;
return setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval));
}
/** Set the keepalive options on the socket
* This also enables TCP keepalive on the socket
*
* @param fd file descriptor
* @param fd file descriptor
* @return 0 on success -1 on failure
*/
int set_tcp_keepalive_cfg(int sockfd, const struct KeepConfig *cfg)
{
int rc;
//first turn on keepalive
rc = set_tcp_keepalive(sockfd);
if (rc != 0) {
return rc;
}
//set the keepalive options
rc = setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPCNT, &cfg->keepcnt, sizeof cfg->keepcnt);
if (rc != 0) {
return rc;
}
rc = setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE, &cfg->keepidle, sizeof cfg->keepidle);
if (rc != 0) {
return rc;
}
rc = setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPINTVL, &cfg->keepintvl, sizeof cfg->keepintvl);
if (rc != 0) {
return rc;
}
return 0;
}
Despite its name, keep-alive is not about keeping connection alive, it is about exchanging packets periodically to make sure that there is a network path between peers. 尽管名称如此,但keep-alive并不是要保持连接活动,而是定期交换数据包以确保对等体之间存在网络路径。 It kills connections that would survive extended network outages while idle.
它会在空闲时杀死延长网络中断的连接。
Due to this behavior, keep-alive should not be used unless there is good reason, like telnet or SSH connections where it is reasonable to kill the session when client gets out of touch. 由于这种行为,除非有充分的理由,例如telnet或SSH连接,否则不应使用keep-alive,在客户端失去联系时终止会话是合理的。
Most probably it is the server that is closing connection after n hours regardless of keepalive usage, due to some connection handling policy. 最有可能的是,由于某些连接处理策略,服务器在n小时后关闭连接,而不管keepalive使用情况如何。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.