java - 如何防止java.net.ConnectException : Connection timed out?

标签 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)

最佳答案

这意味着驱动程序尝试在该端口上打开与该 IP 的连接,但没有人在监听该端口,因此没有人应答,因此出现“连接超时”消息。

正如 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 '^]'.

这意味着端口已打开并且不会抛出异常。 (我的电脑上有MySQL监听3306)。

很可能是您数据库中的 IP 和端口 connection string (参见此处的 reference )是错误的,例如设置为没有数据库正在监听的某个端口。

查看此answer以及 HTTP Error 408 Request timeout 的解释(这是同样的错误)。

编辑:

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

  • 连接被拒绝表示没有人在监听给定的端口
  • 连接超时 表示无法建立连接,或者如 EJP 所述,连接尝试超时。

假设您在 Java 中有以下行,最终 JDBC 驱动程序会在某个时刻执行(类似的操作):

Socket s = new Socket(IP,PORT);

在执行此行之前,(TCP) 连接已关闭执行完该行并且没有抛出异常,连接就建立(如 apidoc for constructor 中所述)。 执行该行时,实际发生的情况是(称为TCP三向握手):

TCP threeway handshake

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

首先,假设 IP 是可访问的(例如,从命令行ping IP 开始向控制台打印响应时间),但端口上没有进程监听。三向握手将按照绘制的方式进行,但一旦连接建立,服务器将找不到任何在该端口上监听的进程,并将立即启动连接关闭 - Connection将抛出拒绝

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

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

    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());
    }

输出:

connect attempt duration measured in ms:1009
connect timed out

apidoc for connect method 中也有说明。 。因此,如果目标 IP 无法访问,则会抛出此异常。然而,导致网络上的计算机无法访问的原因可能有很多。我首先想到的是主机已关闭,或者改写EJP的评论:

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

关于java - 如何防止java.net.ConnectException : Connection timed out?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14213287/

相关文章:

java - 当您有名为 "Users"的表时出现 H2 JDBC 错误

java - JTOpen 程序调用套接字超时

Android在蓝牙套接字上设置超时

java - SQL 语句中的哪个通配符必须用于 Access *.mdb 文件查询(使用 Java 和 JDBC :ODBC bridge)

java - 具有多个子项的树的数组中的通用类型

java - Tomcat : java.net.ConnectException: 连接被拒绝

java - 通用类型数组 - 无法从类型变量中进行选择

jdbc - Hive JDBC 与 CLI 客户端

java - Java 中的多线程不考虑套接字超时?

java - Selenium WebDriver - Java - 更改用户代理