我已经编写了一个程序,它通过随机代理将httpurlconnection打开到网站。我的httpurlConnection称为 conn 。现在我知道,其中一些代理可能太慢了,所以我将连接的超时设置为使用conn.setConnectTimeout(40000)
和conn.setReadTimeout(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();
}
有原因导致连接失败的原因,因此在许多情况下,我到达最后一个接管块并获得以下输出:
消息:连接时间:连接mytimeout:40000实际时间传递:21012
消息:连接时间:连接mytimeout:40000实际时间:21016
消息:连接时间:连接mytimeout:40000实际时间传递:21010
消息:连接时间:连接mytimeout:40000实际时间:21009
所以我的问题是:我将超时设置为40000毫秒,但是在大约21000毫秒之后,我得到了一个"连接时间" - 响应,你们中有人知道为什么这是吗?
编辑:我正在使用Windows 7,现在我将e.printstacktrace()添加到接管块中,就像评论中所述。到目前为止,谢谢。现在的输出为(示例):
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
表示由于没有程序在端口上侦听等原因而拒绝连接。
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
?
我尝试了以下测试用例:
+------------+------------+----------------+------------------+---------------------------------+
| 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
并将代理标记为无效/down
根据我的经验,httpurlconnection在名称分辨率期间不会超时。如果您的设备已缓存目标地址,则将正确超时。
用于测试目的,请使用您的IP地址。
这通常在我的移动设备上发生。