-1

最近我们在客户端应用程序连接到服务器时遇到了 SocketTimeoutException。客户端应用程序使用 Axis1.4 作为 SOAP 引擎。我们已经将套接字的连接超时和读取超时设置为 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?这是一个错误吗?从这里看应用程序需要自己处理超时,这很奇怪。

4

1 回答 1

-2

我们已经将套接字的连接超时和读取超时设置为 20 秒

不,你没有。您调用SSLSocketFactory.createSocket(host, port)了 ,它没有超时参数。所以使用了默认值。

这是一个错误吗?

不,您没有使用连接超时,因此它使用默认值。

为什么 sun 的实现硬编码为 0?

因为这是默认值。

于 2016-02-10T01:50:50.687 回答