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;
}
2条答案
按热度按时间qxsslcnc1#
只启用keepalive。您将获得keepalive探测器的默认计时器,可以使用以下命令查看:
通常默认值为几个小时。
如果您想更改默认计时器,您可以使用以下命令:
使用此处的帮助函数:
j8ag8udp2#
尽管名字叫keep-alive,但它并不是要保持连接的活动,而是要定期交换数据包,以确保对等点之间存在网络路径,它会在空闲时杀死那些能够在长时间网络中断后幸存下来的连接。
由于此行为,除非有充分的理由,否则不应使用keep-alive,如telnet或SSH连接,在这些连接中,当客户端无法访问时,可以终止会话。
很可能是服务器由于某些连接处理策略而在n小时后关闭连接,而不管keepalive使用情况如何。
最新消息:Dror Harari的评论给这种情况又增加了一条皱纹:NAT中间路由器。一个完全空闲的连接会被它们关闭,而主机并不知道,它们认为它们有连接,但实际上它们没有了。使用某种keepalive(在TCP或应用程序协议级别)是一个有效的解决方案。