问题描述
我编写了一个程序,通过随机代理打开httpurlconnection到网站。我的httpurlconnection被称为 conn 。现在我知道,其中一些代理可能太慢了,所以我用 conn.setConnectTimeout(40000)
和<$将连接超时设置为40000毫秒c $ c> conn.setReadTimeout(40000)。
I've written a programm that opens a httpurlconnection to a website through random proxies. My httpurlconnection is called conn. Now I know, that some of those proxies might be too slow, so i've set the timeout of the connection to 40000 milliseconds with conn.setConnectTimeout(40000)
and conn.setReadTimeout(40000)
.
这样做后,我得到了这段代码:
After doing so, i got this code:
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并得到以下输出:
There are reasons why the connection could fail, so in many cases i get to the last catch-block and get the following output:
消息:连接超时:connect MyTimeout:40000实际通过时间:21012
Message: Connection timed out: connect MyTimeout:40000 Actual time passed: 21012
消息:连接超时:连接MyTimeout:40000实际通过时间:21016
Message: Connection timed out: connect MyTimeout:40000 Actual time passed: 21016
消息:连接超时:connect MyTimeout:40000实际传递时间:21010
Message: Connection timed out: connect MyTimeout:40000 Actual time passed: 21010
消息:连接超时:connect MyTimeout:40000实际传递时间:21009
Message: Connection timed out: connect MyTimeout:40000 Actual time passed: 21009
所以我的问题是:我已将超时设置为40000毫秒,但我得到连接超时 - 大约21000毫秒后的响应,你们中的任何人都知道为什么会这样吗?
So my question would be: I have set the timeout to 40000 milliseconds, but i get a "Connection timed out"-response after about 21000 milliseconds, does any of you know why that is?
编辑:我正在使用Windows 7而我现在将e.printStackTrace()添加到了catch中-block,就像在评论中说的那样。谢谢到目前为止。现在的输出是(示例):
im using windows 7 and i now added the e.printStackTrace() to the catch-block, like told in the comments. thanks so far. the output now is (example):
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.<init>(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
表示由于没有进程正在侦听端口等原因而远程拒绝连接。
Look at the exception you got:
The biggest clue: You are getting java.net.ConnectException
As per javadoc, java.net.ConnectException
signifies that connection was refused remotely for reasons such as no process is listening on the port.
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 (e.g., no process is listening on the remote
address/port)
您在HttpUrlConnection中配置的内容:
连接超时(假设远程端口接受连接)。如果连接超时到期,则会得到 java.net.SocketTimeoutException
而不是 java.net.ConnectException
。
那么,是什么导致 java.net.ConnectException
?
我尝试了以下测试用例:
So, what is causing java.net.ConnectException
?
I tried the following test cases:
+------------+------------+----------------+------------------+---------------------------------+
| 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的原因
- Case #1, #3 are the happy paths in which all configs are correct
- In case #4, we get a
java.net.SocketTimeoutException
because java process is able to establish connection (to the proxy port), but does not get any data to read as target host's port number is invalid - In case #2, #5 we get
java.net.ConnectException
because the port at which java process attempts to write/read is invalid - The connection timeout value does not hold good for cases where no process is listening on the port at which java process is attempting to connect. That's why you get ConnectException before timeout expires
- 您尝试连接的某些代理必须关闭。因此java进程抛出
java.net.ConnectException
- 最好抓住
java.net.ConnectException
并将代理标记为无效/关闭 - Some of the proxies you were trying to connect to, must be down. Hence java process threw
java.net.ConnectException
- It's better to catch
java.net.ConnectException
and mark the proxy as invalid/down
消息:连接被拒绝:连接MyTimeout:10000实际传递时间:6549
java.net.ConnectException:拒绝连接:在java.net.DualStackPlainSocketImpl.waitForConnect(本机方法)连接
java.net.DualStackPlainSocketImpl.socketConnect上的
(DualStackPlainSocketImpl。 java:85)
....
....
结论:
这篇关于Java HTTPUrlConnection超时不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!