如何防止java.net.ConnectException:连接超时?

时间:2013-01-08 10:49:05

标签: java jdbc socket-timeout-exception

任何正文都可以解释java.net.ConnectException:连接超时

Caused by: java.net.ConnectException: Connection timed out 
    at java.net.PlainSocketImpl.socketConnect(Native Method) 
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:337) 
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:198) 
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:180) 
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:391) 
    at java.net.Socket.connect(Socket.java:579) 
    at sun.reflect.GeneratedMethodAccessor11.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at net.sourceforge.jtds.jdbc.SharedSocket.createSocketForJDBC3(SharedSocket.java:289) 
    at net.sourceforge.jtds.jdbc.SharedSocket.(SharedSocket.java:250) 
    at net.sourceforge.jtds.jdbc.ConnectionJDBC2.(ConnectionJDBC2.java:297)

3 个答案:

答案 0 :(得分:1)

这意味着驱动程序试图在该端口上打开与该IP的连接,但是没有人监听该端口,因此没有人回答“连接超时”消息。 / p>

正如Arunn P Johny建议的那样,如果你打开一个命令行并运行

telnet localhost 4545

它会像这样响应

Trying 127.0.0.1...
telnet: Unable to connect to remote host: Connection refused

这意味着没有人在听。例如。尝试在该端口上打开套接字(数据库连接)将导致连接超时异常。 (选择端口4545是因为我的计算机上没有任何东西在监听)

如果它以其他任何方式作出回应,例如

telnet localhost 3306

Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.

这意味着端口已打开,并且不会抛出异常。 (我的计算机上有330监听MySQL)。

数据库connection string中的IP和端口很可能是错误的,例如reference}。设置为某个没有数据库正在侦听的端口。

请参阅此answer以及HTTP Error 408 Request timeout的说明(这是同样的错误)。

编辑:

我最初给出了一个错误的答案(正如EJP指出的那样)。建立连接时,这两个错误都发生在TCP级别上:

  • Connection refused表示没有人在侦听给定端口
  • Connection timeout表示无法建立连接,或者如EJP所述,连接尝试超时。

假设您在Java中有以下行,最终JDBC驱动程序在某些时候会这样做(类似):

Socket s = new Socket(IP,PORT);

执行此行之前,(TCP)连接已关闭执行此行之后,没有抛出任何异常,连接已建立(如apidoc for constructor中所述)。 此行正在执行时,这就是实际发生的事情(它被称为 TCP三次握手):

TCP threeway handshake

让我们回顾两种可能的情况。

首先,假设IP可以访问(例如ping IP从命令行开始向控制台打印响应时间)但是没有进程监听PORT。三次握手将按照绘制的方式进行,但是一旦连接建立,服务器就不会发现任何进程正在侦听该端口,并将启动关闭连接immediatley - {{1}将被抛出。

这是此异常的唯一可能结果

现在,让我们假设IP无法访问。客户端将发送连接请求,但永远不会收到连接授予。经过一段时间(超时)后,Connection refused将被抛出。请考虑以下代码:

Connection timeout

输出:

    String reachableIP = "127.0.0.1";
    String unreachableIP = "10.192.0.1";
    int connTimeout = 1000;
    long duration = 0;        
    try {
        duration = System.currentTimeMillis();            
        new Socket().connect(new InetSocketAddress(unreachableIP, 3306), connTimeout);
    }
    catch (Exception e) {
        duration = System.currentTimeMillis() - duration;           
        System.out.println("connect attempt duration measured in ms:" + duration);
        System.out.println(e.getMessage());
    }

这也在apidoc for connect method中说明。因此,如果目标IP无法访问,则会抛出此异常。但是,网络上计算机的不可达性的原因可能很多。我想到的第一件事是主持人被关闭,或者改写EJP的评论:

有许多原因,例如积压队列填满或可能导致此异常的网络连接问题。

答案 1 :(得分:1)

如果你能ping sql server,那么这可能是sql server实例中TCP / IP配置的问题。

您可以参考this question on how to enable TCP/IP,也可以参考Microsoft的thisthis文章。

  
      
  1. 启动SQL Server配置管理器。单击“开始”,指向“所有程序”,然后单击“Microsoft SQL Server”。单击“配置工具”,然后单击“SQL Server配置管理器”。
  2.   
  3. 在SQL Server配置管理器的控制台窗格中,展开“SQL Server网络配置”。
  4.   
  5. 在控制台窗格中,单击“协议”。
  6.   
  7. 在详细信息窗格中,右键单击“TCP / IP”,然后单击“启用”。
  8.   
  9. 在控制台窗格中,单击“SQL Server服务”。
  10.   
  11. 在详细信息窗格中,右键单击“SQL Server()”,然后单击“重新启动”以停止并重新启动SQL Server服务。
  12.   

答案 2 :(得分:0)

在大多数情况下,由于您的互联网代理,会出现连接超时问题。 请确保您已在IDE的网络设置中提供了所有代理设置以及默认的系统代理设置。

如果问题仍然存在,你必须尝试没有代理连接...希望它有帮助