【问题标题】:What is the exact difference between "java.net.ConnectException: Connection timed out" and "java.net.SocketTimeoutException: connect timed out"?“java.net.ConnectException:连接超时”和“java.net.SocketTimeoutException:连接超时”之间的确切区别是什么?
【发布时间】:2015-10-31 05:06:13
【问题描述】:

在我的日志中,我可以找到以下两个堆栈跟踪

Caused by: java.net.ConnectException: Connection 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) 
at sun.net.NetworkClient.doConnect(NetworkClient.java:175)  
at sun.net.www.http.HttpClient.openServer(HttpClient.java:432)  
at sun.net.www.http.HttpClient.openServer(HttpClient.java:527)  
at sun.net.www.http.HttpClient.<init>(HttpClient.java:211)  
at sun.net.www.http.HttpClient.New(HttpClient.java:308) 
at sun.net.www.http.HttpClient.New(HttpClient.java:326) 
at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:1168)    
at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1147)   
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:998) 
at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:932)  
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLConnection.java:1282)    
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1257) 
at com.sun.xml.internal.ws.transport.http.client.HttpClientTransport.getOutput(HttpClientTransport.java:104)    ... 127 more

和

Caused by: java.net.SocketTimeoutException: 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) 
at sun.security.ssl.SSLSocketImpl.connect(SSLSocketImpl.java:656)   
at sun.net.NetworkClient.doConnect(NetworkClient.java:175)  
at sun.net.www.http.HttpClient.openServer(HttpClient.java:432)  
at sun.net.www.http.HttpClient.openServer(HttpClient.java:527)  
at sun.net.www.protocol.https.HttpsClient.<init>(HttpsClient.java:275)  
at sun.net.www.protocol.https.HttpsClient.New(HttpsClient.java:371) 
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.getNewHttpClient(AbstractDelegateHttpsURLConnection.java:191)  
at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1147)   
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:998) 
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:177)   
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLConnection.java:1282)    
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1257) 
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:250)   
at com.sun.xml.internal.ws.transport.http.client.HttpClientTransport.getOutput(HttpClientTransport.java:104)    ... 50 more

在使用 JAXWS-RI(参考实现)调用 Web 服务期间会发生这两个异常。这两个例外之间的确切区别是什么。

为了配置超时,我在上下文中设置了一些属性,一个是连接超时:

BindingProvider bindingProvider = (BindingProvider) port;
Map<String, Object> context = bindingProvider.getRequestContext();
context.put(JAXWSProperties.REQUEST_TIMEOUT, 90000);
context.put(JAXWSProperties.CONNECT_TIMEOUT, 90000);

据我从日志中可以看出,只有 java.net.SocketTimeoutException 似乎尊重 JAXWSProperties.CONNECT_TIMEOUT 设置。

java.net.ConnectExceptions 在 90 秒结束前出现。

【问题讨论】:

    标签: java timeout jax-ws httpurlconnection


    【解决方案1】:

    我想我的问题已经回答了here。

    提到的两个异常来自本机代码。正如user5436 已经提到的,SocketTimeoutExceptions 发生在设置超时并且无法在所需时间内建立连接时。 ConnectException 在尝试建立连接时发生错误时抛出。令人困惑的是,这也可能是连接超时。

    【讨论】:

      【解决方案2】:

      我怀疑没有证据证明其中一个来自connect(..., timeout) 路径,另一个来自未指定连接超时的路径。在前一种情况下,我希望SocketTimeoutException,在后一种情况下ConnectException。

      【讨论】:

        【解决方案3】:

        它们在网络传输层方面相当低级,并且在 TCP/IP 状态机的不同状态下被错误抛出。如果有兴趣,您可以研究 TCP 套接字图,但大多数网络应用程序(JAX-WS 是)用户或程序员不需要关心这些低级细节,除了网络不工作的事实。

        它们来自不同的代码路径,一个是建立 http 连接,另一个是 https。 Https是基于SSL的,即安全套接字层,它试图连接不同参数的套接字。

        底线是这些代码路径是由其他人编写的,可能是古代程序员。当时他们决定抛出一个异常而不是另一个。我们不必大惊小怪。

        【讨论】:

        • 一个是 HTTP 一个是 HTTPS 的事实是无关紧要的。这两个异常都是由相同的方法引发的。 SSL 不会“尝试使用不同的参数连接套接字”。
        • 在将其他人的 cmets 标记为不相关之前,您应该找到并阅读源代码文件和上面的堆栈跟踪。
        • 在HTTP的情况下,连接是由java中省略timeOut参数的包装函数New()创建的,这意味着传入默认的-1,最终传递给socket connect()。在 HTTPS 的情况下,用户指定的 timeOut 被传入。这也解释了为什么设置在一个中得到尊重,而不是另一个。然后在代码路径中,它们根据不同的timeOuts(未指定一个)被不同的中断,因此不同的Exceptions。
        猜你喜欢
        • 2020-06-22
        • 1970-01-01
        • 2011-08-05
        • 2014-03-01
        • 2013-12-01
        • 1970-01-01
        • 1970-01-01
        • 2015-09-27
        • 1970-01-01
        相关资源
        最近更新 更多