Java的HttpURLConnection类超时不工作(Java HTTPUrlConnectio

2019-07-17 13:51发布

我已经写了通过随机代理打开一个HttpURLConnection类的网站PROGRAMM。 我HttpURLConnection类被称为美国康涅狄格州 。 现在我知道,这其中的一些代理的可能太慢,所以我已经设置与连接至40000毫秒超时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和我现在的IM添加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.<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

Answer 1:

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)

What you configured in HttpUrlConnection:
The timeout for connection (given that the remote port accepts connection). If the connection timeout expires, you get a java.net.SocketTimeoutException and not a 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       |
   +------------+------------+----------------+------------------+---------------------------------+ 
  • 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

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) .... ....

Conclusion:

  • 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


Answer 2:

根据我的经验,HttpURLConnection类不会在名称解析过程超时。 如果您的设备缓存中的目标地址,那么它将正确超时。

出于测试目的,在代码中使用您的IP地址。

这通常发生在我身上在移动设备上。



文章来源: Java HTTPUrlConnection timeout does not work