java 设置tcp连接超时_java - TCP套接字连接是否具有“保持活动状态”?

现在这个套接字连接是否会永远保持打开状态,或者是否存在与之相关的超时限制,类似于HTTP keep-alive?

简短的回答是,是的,有一个超时,它通过TCP Keep-Alive强制执行。

如果要配置保持活动超时,请参阅下面的“更改TCP超时”部分。

介绍

TCP连接由两个插槽组成,每个插槽位于连接的两端。 当一方想要终止连接时,它会发送另一方确认的ACK数据包并关闭其套接字。

然而,在此之前,双方将无限期地保持其套接字开放。 这使得一方可能有意或由于某些错误而关闭其套接字,而无需通过ACK通知另一端。为了检测这种情况并关闭过时连接,使用TCP Keep Alive进程。

保持活力过程

有三个可配置属性可确定Keep-Alives的工作方式。 在Linux上他们是1:

ACK默认7200秒

ACK默认9

ACK默认75秒

这个过程是这样的:

客户端打开TCP连接

如果连接静默ACK秒,则发送一个空的keepintvl数据包.1

服务器是否以相应的ACK响应?没有等待ACK秒,然后发送另一个keepintvl

重复,直到已发送的ACK探测数等于keepintvl。

如果此时未收到响应,请发送ACK并终止连接。

是:返回第2步

默认情况下,在大多数操作系统上启用此过程,因此一旦另一端无响应2小时11分钟(7200秒+ 75 * 9秒),则会定期修剪死TCP连接。

陷阱

2小时默认值

由于默认情况下连接空闲两小时后才开始进程,因此过时的TCP连接可能会在修剪之前停留很长时间。 这对于诸如数据库连接之类的昂贵连接尤其有害。

Keep-Alive是可选的

根据RFC 1122 4.2.3.6,响应和/或中继TCP Keep-Alive数据包是可选的:

实现者可以在其TCP实现中包含“keep-alives”,   虽然这种做法并未得到普遍接受。 如果保持活着   包含,应用程序必须能够为每个打开或关闭它们   TCP连接,它们必须默认为关闭。

...

这是非常的   重要的是要记住不包含数据的ACK段   由TCP可靠传输。

原因是Keep-Alive数据包不包含任何数据,并且不是严格必要的,如果过度使用,可能会堵塞互联网的管道。

然而,在实践中,我的经验是,随着带宽变得越来越便宜,这种担忧随着时间的推移逐渐减少; 因此,通常不会丢弃Keep-Alive数据包。 例如,亚马逊EC2文档间接认可了Keep-Alive,因此如果您使用AWS托管,您可能会安全地依赖Keep-Alive,但您的里程可能会有所不同。

更改TCP超时

每个插座

不幸的是,由于TCP连接是在操作系统级别上管理的,因此Java不支持在每个套接字级别配置超时,例如ACK.我发现有一些尝试3使用Java本机接口(JNI)创建调用本机代码的Java套接字 配置这些选项,但似乎都没有广泛的社区采用或支持。

相反,您可能被迫将配置作为一个整体应用于操作系统。 请注意,此配置将影响整个系统上运行的所有TCP连接。

Linux的

可以在中找到当前配置的TCP Keep-Alive设置

ACK

ACK

ACK

您可以更新以下任何内容:

# Send first Keep-Alive packet when a TCP socket has been idle for 3 minutes

$ echo 180 > /proc/sys/net/ipv4/tcp_keepalive_time

# Send three Keep-Alive probes...

$ echo 3 > /proc/sys/net/ipv4/tcp_keepalive_probes

# ... spaced 10 seconds apart.

$ echo 10 > /proc/sys/net/ipv4/tcp_keepalive_intvl

这种变化不会在重启后持续存在。 要进行持久更改,请使用ACK:

sysctl -w net.ipv4.tcp_keepalive_time=180 net.ipv4.tcp_keepalive_probes=3 net.ipv4.tcp_keepalive_intvl=10

Mac OS X.

可以使用ACK查看当前配置的设置:

$ sysctl net.inet.tcp | grep -E "keepidle|keepintvl|keepcnt"

net.inet.tcp.keepidle: 7200000

net.inet.tcp.keepintvl: 75000

net.inet.tcp.keepcnt: 8

值得注意的是,与使用秒的Linux相比,Mac OS X以毫秒为单位定义了ACK和keepintvl。

可以使用ACK设置属性,这将在重新启动后保留这些设置:

sysctl -w net.inet.tcp.keepidle=180000 net.inet.tcp.keepcnt=3 net.inet.tcp.keepintvl=10000

或者,您可以将它们添加到ACK(如果文件不存在,则创建该文件)。

$ cat /etc/sysctl.conf

net.inet.tcp.keepidle=180000

net.inet.tcp.keepintvl=10000

net.inet.tcp.keepcnt=3

视窗

我没有Windows机器来确认,但您应该在注册表中找到相应的TCP Keep-Alive设置

ACK

脚注

1.有关更多信息,请参阅ACK。

2.此数据包通常被称为“保持活动”数据包,但在TCP规范中,它只是一个常规的ACK数据包。 像Wireshark这样的应用程序能够通过元数据分析将其标记为“保持活动”数据包,它包含参考插槽上先前通信所包含的序列和确认号。

我从谷歌基本搜索中找到的一些例子是lucwilliams / JavaLinuxNet和flonatel / libdontdie。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值