linux tcp connection timeout,linux上TCP connection timeout问题解决办法

本文深入探讨了Linux系统中TCP连接超时的问题,并详细解释了Java应用中connect timeout异常产生的原因及其处理机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

linux上TCP connection timeout问题解决办法

最近在产线上经常出现connection timeout的问题,先看看Java 中关于connection timeout 的异常如何产生

JAVA中的timeout

java.net.SocketTimeoutException: connect timed out 客户端异常:connect timed out at java.net.PlainSocketImpl.socketConnect(Native Method) at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:345) at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) at java.net.Socket.connect(Socket.java:589)

我们能经常看到的connect timed out异常产生,看一下java 是如何生成这个异常

plainsocketimpl.c 中

while (1) { jlong newTime; #ifndef USE_SELECT { struct pollfd pfd; pfd.fd = fd; pfd.events = POLLOUT; errno = 0; connect_rv = NET_Poll(&pfd, 1, timeout); } #else { fd_set wr, ex; struct timeval t; t.tv_sec = timeout / 1000; t.tv_usec = (timeout % 1000) * 1000; FD_ZERO(&wr); FD_SET(fd, &wr); FD_ZERO(&ex); FD_SET(fd, &ex); errno = 0; connect_rv = NET_Select(fd+1, 0, &wr, &ex, &t); } #endif if (connect_rv >= 0) { break; } if (errno != EINTR) { break; } /* * The poll was interrupted so adjust timeout and * restart */ newTime = JVM_CurrentTimeMillis(env, 0); timeout -= (newTime - prevTime); if (timeout <= 0) { connect_rv = 0; break; } prevTime = newTime; } /* while */ if (connect_rv == 0) { JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException", "connect timed out"); /* * Timeout out but connection may still be established. * At the high level it should be closed immediately but * just in case we make the socket blocking again and * shutdown input & output. */ SET_BLOCKING(fd); JVM_SocketShutdown(fd, 2); return; }

这里可以看到在做connect的时候,是调用 NET_Poll 或者 NET_Select, 在linux 上就是使用 poll/select

当发生timeout的时候connect_rv=0  ,这里有个注意点虽然在poll/select 是传入timeout的时间,但是这是会被打断的,connect_rv返回的值为-1 ,所以jvm里面重新计算了timeout , 确保timeout 的时间片已经运行完了,才推出循环。

newTime = JVM_CurrentTimeMillis(env, 0); timeout -= (newTime - prevTime); if (timeout <= 0) { connect_rv = 0; break; }

同时设置connect_rv 为0, 也是下面只有当connect_rv为0的时候才抛出connect timeout

什么是connect timeout ?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值