Java HTTPUrlConnection超时不起作用
我编写了一个程序,通过随机代理打开httpurlconnection到网站。 我的httpurlconnection叫做conn 。 现在我知道,其中一些代理可能太慢了,所以我用conn.setConnectTimeout(40000)
和conn.setReadTimeout(40000)
将连接超时设置为40000毫秒。
这样做后,我得到了这段代码:
long diff = 0; long starttime = 0; long endtime = 0; try { starttime = System.currentTimeMillis(); conn.connect(); endtime = System.currentTimeMillis(); diff = endtime - starttime; if (endtime <= starttime + conn.getConnectTimeout()) { //Trying to read sourecode InputStreamReader isrConn = new InputStreamReader(conn.getInputStream()); BufferedReader brConn = new BufferedReader(isrConn); line = brConn.readLine(); while (line != null) { response += line + "\t"; try { line = brConn.readLine(); } catch (IOException e) { printError("Reading sourcecode failed."); } } } else { response = "blabla."; } // If conn.connect failed } catch (IOException e) { endtime = System.currentTimeMillis(); diff = endtime - starttime; response = "Message: "+e.getMessage() +" MyTimeout:"+ conn.getConnectTimeout() +" Actual time passed: "+ diff; e.printStackTrace(); }
有连接可能失败的原因,所以在很多情况下我会到达最后一个catch-block并获得以下输出:
消息:连接超时:连接MyTimeout:40000实际传递时间:21012
消息:连接超时:连接MyTimeout:40000实际传递时间:21016
消息:连接超时:连接MyTimeout:40000实际传递时间:21010
消息:连接超时:连接MyTimeout:40000实际通过时间:21009
所以我的问题是:我已经将超时设置为40000毫秒,但是我在大约21000毫秒后得到“连接超时” – 响应,你们中的任何人都知道为什么会这样吗?
编辑:即时通讯使用Windows 7,我现在将e.printStackTrace()添加到catch块,就像在评论中说的那样。 谢谢到目前为止。 现在的输出是(例子):
java.net.ConnectException: Connection timed out: connect at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method) at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source) at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source) at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source) at java.net.AbstractPlainSocketImpl.connect(Unknown Source) at java.net.PlainSocketImpl.connect(Unknown Source) at java.net.Socket.connect(Unknown Source) at sun.net.NetworkClient.doConnect(Unknown Source) at sun.net.www.http.HttpClient.openServer(Unknown Source) at sun.net.www.http.HttpClient$1.run(Unknown Source) at sun.net.www.http.HttpClient$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at sun.net.www.http.HttpClient.privilegedOpenServer(Unknown Source) at sun.net.www.http.HttpClient.openServer(Unknown Source) at sun.net.www.http.HttpClient.(Unknown Source) at sun.net.www.http.HttpClient.New(Unknown Source) at sun.net.www.http.HttpClient.New(Unknown Source) at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(Unknown Source) at sun.net.www.protocol.http.HttpURLConnection.plainConnect(Unknown Source) at sun.net.www.protocol.http.HttpURLConnection.connect(Unknown Source) at TestThread.getSourcePage(TestThread.java:361) at TestThread.aChecker(TestThread.java:216) at TestThread.getNextProxy(TestThread.java:169) at TestThread.getNextC(TestThread.java:157) at TestThread.aChecker(TestThread.java:273) at TestThread.getNextProxy(TestThread.java:169) at TestThread.aChecker(TestThread.java:295) at TestThread.getNextProxy(TestThread.java:169) at TestThread.getNextC(TestThread.java:157) at TestThread.run(TestThread.java:103) at java.lang.Thread.run(Unknown Source) Message: Connection timed out: connect MyTimeout:40000 Actual time passed: 21015
看看你得到的例外情况:
最大的线索:您正在获取java.net.ConnectException
根据javadoc, java.net.ConnectException
表示由于没有进程正在侦听端口等原因而远程拒绝连接。
public class ConnectException extends SocketException Signals that an error occurred while attempting to connect a socket to a remote address and port. Typically, the connection was refused remotely (eg, no process is listening on the remote address/port)
您在HttpUrlConnection中配置的内容:
连接超时(假设远程端口接受连接)。 如果连接超时到期,则会得到java.net.SocketTimeoutException
而不是java.net.ConnectException
。
那么,是什么导致java.net.ConnectException
?
我尝试了以下测试用例:
+------------+------------+----------------+------------------+---------------------------------+ | Valid Host | Valid Port | Valid Proxy IP | Valid Proxy Port | Exception | +------------+------------+----------------+------------------+---------------------------------+ #1 | yes | yes | -NA- | -NA- | -- none -- | #2 | yes | no | -NA- | -NA- | java.net.ConnectException | +------------+------------+----------------+------------------+---------------------------------+ #3 | yes | yes | yes | yes | -- none -- | #4 | yes | no | yes | yes | java.net.SocketTimeoutException | #5 | yes | yes | yes | no | java.net.ConnectException | +------------+------------+----------------+------------------+---------------------------------+
- 案例#1,#3是所有配置都正确的快乐路径
- 在#4的情况下,我们得到一个
java.net.SocketTimeoutException
因为java进程能够建立连接(到代理端口),但是没有得到任何数据,因为目标主机的端口号无效 - 在#2,#5的情况下,我们得到
java.net.ConnectException
因为java进程尝试写入/读取的端口无效 - 对于没有进程正在侦听java进程尝试连接的端口的情况,连接超时值不适用。 这就是你在超时到期之前得到ConnectException的原因
Message: Connection refused: connect MyTimeout:10000 Actual time passed: 6549 java.net.ConnectException: Connection refused: connect at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method) at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:85) .... ....
结论:
- 您尝试连接的某些代理必须关闭。 因此java进程抛出了
java.net.ConnectException
- 最好捕获
java.net.ConnectException
并将代理标记为无效/关闭
根据我的经验,HttpUrlConnection在名称解析期间不会超时。 如果您的设备已缓存目标地址,则它将正确超时。
出于测试目的,请在代码中使用您的IP地址。
这通常发生在移动设备上。
- httpurlconnection线程安全
- 将HTTP 407错误作为IOException
- -POST Json with HttpUrlConnection
- HttpURLConnection conn.getRequestProperty返回null
- getRequestProperty(“Authorization”)始终返回null
- 如何在HttpURLConnection中覆盖http-header“Host”?
- 在响应完成之前关闭HttpURLConnection
- HttpURLConnection c = URL.openConnection(); c.setRequestProperty()不起作用
- 当我调用connect()时,Java HttpURLConnection无法连接