微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Java HTTPUrlConnection超时不起作用

我写了一个程序,通过随机代理打开一个网站的httpurl连接.我的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块并得到以下输出

消息:连接超时:连接MyTimeout:40000实际通过时间:21012

消息:连接超时:连接MyTimeout:40000实际传递时间:21016

消息:连接超时:连接MyTimeout:40000通过的实际时间:21010

消息:连接超时:连接MyTimeout:40000通过的实际时间:21009

所以我的问题是:我将超时设置为40000毫秒,但是在大约21000毫秒之后我得到一个“连接超时” – 响应,你们有没有知道为什么呢?

编辑:im使用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.<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的原因

消息:连接拒绝:连接MyTimeout:10000实际传递时间:6549
java.net.ConnectException:Connection refused:connect
在java.net.DualStackPlainSocketImpl.waitForConnect(本机方法)
在java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:85)
….
….

结论:

>您尝试连接的某些代理必须关闭.因此java进程抛出java.net.ConnectException>最好抓住java.net.ConnectException并将代理标记为invalid / down

原文地址:https://www.jb51.cc/java/125379.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐