文章目录
java中CTO(connection timed out)
-
在实际开发中经常会碰到
Connection timed out
的问题java.net.ConnectException: Connection timed out (Connection timed out) at java.net.PlainSocketImpl.socketConnect(Native Method) at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) 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) at java.net.Socket.connect(Socket.java:538) at java.net.Socket.<init>(Socket.java:434) at java.net.Socket.<init>(Socket.java:211) at ClientSocketTimeout.main(ClientSocketTimeout.java:8)
-
Connection timed out
是client
发出sync
包,server端在指定的时间内没有回复ack
导致的.没有回复ack
的原因可能是网络丢包、防火墙阻止服务端返回syn的ack包等 -
执行流程
socksSocketImpl.connect(endpoint,timeout) --> remainingMillis(deadlineMillis) //java代码先计算剩余是否超时 --> connectToAddress(this.address, port, timeout) --> doConnect(address, port, timeout) --> native PlainSocketImpl.socketConnect (调用本地方法) --> PlainSocketImpl.c 中的Java_java_net_PlainSocketImpl_socketConnect
PlainSocketImpl.c
openjdk
源码下载地址https://download.java.net/openjdk/jdk8
.PlainSocketImpl.c
的位置在openjdk/jdk/src/solaris/native/java/net
Java_java_net_PlainSocketImpl_socketConnect
-
阻塞模式: 只有timeout小于等于0,才会执行这段代码,可以看出阻塞模式的超时,如果不设置则依赖底层操作系统的超时机制,如果在java层面设置超时,则本质上是通过非阻塞模式实现的
if (timeout <= 0) { connect_rv = NET_Connect(fd, (struct sockaddr *)&him, len); #ifdef __solaris__ if (connect_rv == JVM_IO_ERR && errno == EINPROGRESS ) { /* This can happen if a blocking connect is interrupted by a signal. * See 6343810. */ while (1) { #ifndef USE_SELECT { struct pollfd pfd; pfd.fd = fd; pfd.events = POLLOUT; connect_rv = NET_Poll(&pfd, 1, -1); } #else { fd_set wr, ex; // 清空fdset与所有文件句柄的联系。 FD_ZERO(&wr); //建立文件句柄fd与fdset的联系。 FD_SET(fd, &wr); FD_ZERO(&ex); //