套接字保活不起作用 [英] Socket keepalive not working
问题描述
我有一个客户端 connect() 到服务器,当空闲时,它会在几个小时后超时.我加了setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE...) 1 秒但这并没有什么不同.关于为什么 keepalive 不起作用的任何线索?如果我使用 SOL_TCP 而不是 SOL_SOCKET 会有什么不同吗?这是在 Linux 上.
I have a client connect() to a server, and when idle, it times out after a couple hours. I added setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE...) with 1 sec but it didnt make a difference. Any clues on why keepalive wouldnt work? Would it make a difference if I used SOL_TCP instead of SOL_SOCKET? This is on Linux.
推荐答案
int val = 1;
setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof val)
只启用keepalive.您将获得 keepalive 探测的默认计时器,您可以使用以下命令查看:
Just enables keepalives. You will get the default timers for keepalive probes, which you can view with the command:
sysctl net.ipv4.tcp_keepalive_time
通常默认为几个小时.
如果你想改变默认计时器,你可以使用这个:
If you want to change the default timers, you could use this:
struct KeepConfig cfg = { 60, 5, 5};
set_tcp_keepalive_cfg(fd, &cfg);
这里有辅助函数:
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;
}
这篇关于套接字保活不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!