MAC OS X下如何配置TCP_KEEPALIVE

Posted

技术标签:

【中文标题】MAC OS X下如何配置TCP_KEEPALIVE【英文标题】:How to configure TCP_KEEPALIVE under MAC OS X 【发布时间】:2013-04-07 07:53:05 【问题描述】:

目前我遇到了这个问题:如何检测不可预知的连接中断。

我在linux下使用了SO_KEEPALIVE、TCP_KEEPIDLE、TCP_KEEPINTVL和TCP_KEEPCNT来解决,现在看来运行良好。

但是,我确实花了很长时间才弄清楚如何在 MAC OS X 下解决它。有人建议我转向 netinet/tcp_var.h,但仍然没有找到上述 MACRO。

所以,我的问题是,

MAC OS X下如何实现TCP KEEPALIVE?

P.S.:我的 MAC OS X 版本是 10.8.3,我的 gcc/g++ 版本是 4.2.1

任何回复将不胜感激。

【问题讨论】:

【参考方案1】:

实际上,Darwin (BSD) 比 Linux 更简单。设置 TCP_KEEPALIVE (secs) 选项,以及 SO_KEEPALIVE (bool) 选项:

int on = 1, secs = 10;
setsockopt(skt, SOL_SOCKET,  SO_KEEPALIVE, &on, sizeof on);
setsockopt(skt, IPPROTO_TCP, TCP_KEEPALIVE, &secs, sizeof secs);

要查看默认间隔是多少(如果您刚刚执行了 SO_KEEPALIVE),请使用:

sysctl -A | grep net.inet.tcp.*keep

你可能会看到:

net.inet.tcp.keepidle: 7200000
net.inet.tcp.keepintvl: 75000
net.inet.tcp.keepinit: 75000
net.inet.tcp.always_keepalive: 0

即keepalive 仅适用于设置了 SO_KEEPALIVE 的套接字,空闲超时为 72000.000 毫秒(2 小时)。 HTH。

【讨论】:

应该是sysctl,而不是netstat 但是你如何改变这些值呢?我也需要缩短它们,但我没有看到如何? 正如下面用户“nos”所提到的,这些参数只能由有权在其上运行 sysctl 的人设置......它们确实是系统范围的设置。是的,我知道可能很烂:-)。【参考方案2】:

我认为你应该使用setsockopt(),查看它的手册页

看起来 TCP_KEEPIDLETCP_KEEPINTVLTCP_KEEPCNT 是特定于 Linux 的,您在 OSX 上找不到它们的对应部件。

要设置SO_KEEPALIVE,请执行此操作

int optval = 1;
setsockopt(sock, SOL_SOCKET, &optval, sizeof(optval));

我很久以前使用的另一个技巧是尝试发送 0(零)个字节,这将检查套接字是否仍然存在。要么作为重复的看门狗,要么只是在尝试发送消息之前。

【讨论】:

当然应该是setsockopt(),问题是“如何”。我找不到上述任何选项,即“TCP_KEEPIDLE”、“TCP_KEEPINTVL”、“TCP_KEEPALIVE”和“TCP_KEEPCNT” 我认为问题是关于SO_KEEPALIVE,我看到setsockopt() 存在。 但是,默认情况下,TCP KEEPALIVE 的时间间隔是 2 小时,这绝对是无法忍受的。我的问题的关键是如何在MAC OS X下配置这些。我在linux下没有问题。 @House.Lee 其中一些是 OSX 上的系统范围参数,如 Mischa 的回答中提到的(使用例如 sysctl 命令设置)

以上是关于MAC OS X下如何配置TCP_KEEPALIVE的主要内容,如果未能解决你的问题,请参考以下文章

mac OS X下配置jdk环境变量

Mac OS X下安装和配置Maven

Mac OS X下Maven的安装及配置

Mac OS X下Maven的安装及配置

Mac OS X下安装和配置Maven

Mac OS X下安装和配置Maven