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_KEEPIDLE
、TCP_KEEPINTVL
和 TCP_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的主要内容,如果未能解决你的问题,请参考以下文章