我试图设置tcp keepalive但是这样做我看到了错误
"协议不可用"
int rc = setsockopt(s, SOL_SOCKET, TCP_KEEPIDLE, &keepalive_idle, sizeof(keepalive_idle));
if (rc < 0)
printf("error setting keepalive_idle: %s\n", strerror(errno));
我能够打开keepalive,设置keepalive间隔和计数但是keepalive idle这是keepalive time抛出那个错误而且我从来没有看到任何keepalive数据包通过wireshark和过滤器{{1发送/接收或者使用tcpdump
tcp.analysis.keep_alive
是否需要加载内核模块或其他内容?或者您无法再覆盖全局KEEPIDLE时间。
顺便输出
sudo tcpdump -vv "tcp[tcpflags] == tcp-ack and less 1"
答案 0 :(得分:2)
在我编码的应用程序中,以下工作:
setsockopt(*sfd, SOL_SOCKET, SO_KEEPALIVE,(char *)&enable_keepalive, sizeof(enable_keepalive));
setsockopt(*sfd, IPPROTO_TCP, TCP_KEEPCNT, (char *)&num_keepalive_strobes, sizeof(num_keepalive_strobes));
setsockopt(*sfd, IPPROTO_TCP, TCP_KEEPIDLE, (char *)&keepalive_idle_time_secs, sizeof(keepalive_idle_time_secs));
setsockopt(*sfd, IPPROTO_TCP, TCP_KEEPINTVL, (char *)&keepalive_strobe_interval_secs, sizeof(keepalive_strobe_interval_secs));
尝试将SOL_SOCKET
更改为IPPROTO_TCP
{/ 1}}。
答案 1 :(得分:1)
有一个非常方便的lib可以帮助你,它被称为libkeepalive
:http://libkeepalive.sourceforge.net/
它可以与LD_PRELOAD
一起使用,以便在所有TCP套接字上启用和控制keep-alive。您还可以使用环境变量覆盖keep-alive设置。
我试着用它运行一个tcp服务器:
KEEPIDLE=5 KEEPINTVL=5 KEEPCNT=100 LD_PRELOAD=/usr/lib/libkeepalive.so nc -l -p 4242
然后我连接了一个客户端:
nc 127.0.0.1 4242
我使用Wireshark可视化流量:保持活动数据包在5秒不活动后正好开始(我的系统范围设置为75)。因此,这意味着可以覆盖系统设置。
以下是libkeepalive
设置TCP_KEEPIDLE
的方式:
if((env = getenv("KEEPIDLE")) && ((optval = atoi(env)) >= 0)) {
setsockopt(s, SOL_TCP, TCP_KEEPIDLE, &optval, sizeof(optval));
}
看起来他们使用SOL_TCP
代替SOL_SOCKET
。