强制socket.connect在决定连接不可用之前等待特定时间

时间:2010-11-04 13:21:28

标签: java sockets

我正在使用以下代码段

发出套接字连接
        Socket socket = new Socket();
        InetSocketAddress endPoint = new InetSocketAddress("localhost", 1234);
        try
        {
            socket.connect(endPoint, 30000);
        }
        catch (IOException e)
        {
            e.printStackTrace();
            // Logging
        }

它尝试连接的端点是脱机的,我希望它做的是尝试连接,并使用30000 ms超时,等待结束结果之前的那段时间

目前,似乎没有应用30000参数,因为从我的日志记录的时间戳开始,它似乎在1秒内确定连接失败。

如何强制连接在放弃之前等待一段时间?

13:13:57,685 6235 DEBUG [Thread-7]     - Unable to connect to [localhost:1234]
13:13:58,685 7235 DEBUG [Thread-7]     - Unable to connect to [localhost:1234]
13:13:59,695 8245 DEBUG [Thread-7]     - Unable to connect to [localhost:1234]
13:14:00,695 9245 DEBUG [Thread-7]     - Unable to connect to [localhost:1234]

编辑:API确实说明Connects this socket to the server with a specified timeout value. A timeout of zero is interpreted as an infinite timeout. The connection will then block until established or an error occurs.但是看起来我没有遇到过这样的行为,或者我不服从它,很可能是后者

4 个答案:

答案 0 :(得分:5)

你在这里得到的是正确的。 connect不会坐在套​​接字上等待它看到服务器,它将尝试连接并等待响应。如果没有要连接的东西,它会返回。如果有东西要连接,它会等待超时秒表示响应,如果没有收到则会失败。

答案 1 :(得分:2)

您需要区分几种可能的例外情况。

  1. ConnectException文本“连接被拒绝”,这意味着主机已启动并且可以访问,并且没有任何内容正在侦听端口。这种情况发生得非常快,不会超时。

  2. NoRouteToHostException:这表示存在连接问题。它会立即发生,不会超时。

  3. UnknownHostException:无法通过DNS解析主机名。这种情况会立即发生,或者更确切地说是在DNS延迟很短的情况下发生,并且不会超时。

  4. ConnectException包含任何其他文本:这可能表示目标系统无法响应。通常在防火墙存在时发生。可能会超时。

  5. 通过使用timeout参数调用Socket.connect(),您正在做正确的事情。如果不这样做,或者如果指定零超时,则使用默认系统超时,具体取决于平台,大小为60-75秒。这与Javadoc关于“无限超时”的陈述相反,这是不正确的。此外,您不能通过Socket.connect()以超时参数增加超出此限制的超时。或者,您可以在非阻塞模式下使用java.nio套接字通道使用select()来管理超时,但是仍然无法通过此方法或任何其他方法将超时超出平台默认值。

答案 2 :(得分:0)

发生超时时,抛出一个SocketTimeoutException异常,您不会捕获并记录该异常。 “连接期间发生错误”时会触发IOException。永远不会应用超时,因为事先有错误。

编辑:只是为了澄清:作为套件的TCP / IP有许多细节可能会阻止数据包达到预期的结果(SYN / ACK数据包)。如果计算机通过通知您的应用程序端口已关闭(即没有应用程序在那里运行/侦听)来响应您的SYN数据包,它将触发一个异常,告诉您不可能连接到那个港口。如果您希望以任何方式发送和重新发送SYN数据包,并且知道应用程序将在该端口上联机侦听,则这是在不同的网络层上完成的(据我所知,Java无法访问) -of现成)。

答案 3 :(得分:-1)

连接前尝试socket.setSoTimeout(超时)。