最近,当客户端应用程序连接到服务器时,我们遇到了SocketTimeoutException。客户端应用程序使用Axis1.4作为SOAP引擎。我们已经为socket设置了连接超时和读取超时20秒,但看起来连接超时值不起作用。
在深入研究JDK中的套接字创建之后,使用的套接字工厂是 sun.security.ssl.SSLSocketFactoryImpl ,套接字impl是 sun.security.ssl.SSLSocketImpl 。问题在于SSLSocketImpl的初始化,它将连接超时值硬编码为0,这意味着没有超时:
SSLSocketImpl(SSLContextImpl context, InetAddress host, int port)
throws IOException {
super();
init(context, false);
SocketAddress socketAddress = new InetSocketAddress(host, port);
connect(socketAddress, 0);
}
连接方法是:
/**
* Connects this socket to the server with a specified timeout
* value.
*
* This method is either called on an unconnected SSLSocketImpl by the
* application, or it is called in the constructor of a regular
* SSLSocketImpl. If we are layering on top on another socket, then
* this method should not be called, because we assume that the
* underlying socket is already connected by the time it is passed to
* us.
*
* @param endpoint the <code>SocketAddress</code>
* @param timeout the timeout value to be used, 0 is no timeout
* @throws IOException if an error occurs during the connection
* @throws SocketTimeoutException if timeout expires before connecting
*/
public void connect(SocketAddress endpoint, int timeout)
throws IOException {
if (self != this) {
throw new SocketException("Already connected");
}
if (!(endpoint instanceof InetSocketAddress)) {
throw new SocketException(
"Cannot handle non-Inet socket addresses.");
}
super.connect(endpoint, timeout);
doneConnect();
}
为什么sun的实现硬编码为0?这是一个错误吗?从这看到应用程序需要自己处理超时,这很奇怪。
答案 0 :(得分:-1)
我们已经为socket
设置了连接超时和读取超时20秒
不,你没有。你打电话给SSLSocketFactory.createSocket(host, port)
,它没有超时参数。所以使用了默认值。
这是一个错误吗?
没有。您没有使用连接超时,因此它使用默认值。
为什么sun的实现是硬编码的?
因为这是默认设置。