tcp keepalive - 协议不可用?

时间:2014-05-15 03:57:08

标签: linux sockets tcp

我试图设置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"

2 个答案:

答案 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可以帮助你,它被称为libkeepalivehttp://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