【问题标题】:Java URLConnection TimeoutJava URL连接超时
【发布时间】:2011-03-10 23:20:42
【问题描述】:

我正在尝试从 HTTP URL 解析 XML 文件。我想配置 15 秒的超时,如果 XML 获取时间比这更长,我想报告超时。由于某种原因,setConnectTimeout 和 setReadTimeout 不起作用。代码如下:

          URL url = new URL("http://www.myurl.com/sample.xml");
          URLConnection urlConn = url.openConnection();
          urlConn.setConnectTimeout(15000);
          urlConn.setReadTimeout(15000);
          urlConn.setAllowUserInteraction(false);         
          urlConn.setDoOutput(true);

          InputStream inStream = urlConn.getInputStream();
          InputSource input = new InputSource(inStream);

我正在捕获 SocketTimeoutException。

谢谢 克里斯

【问题讨论】:

  • 挂起吗?发生什么了?你正在阅读流中的内容吗?
  • 不,它不会挂起,也没有异常。解析后我的变量是空的。
  • 那么请看更多代码。
  • 你的问题解决了吗?我遇到了同样的问题..
  • 这不是它的工作原理。读取超时影响单个读取,而不是总读取时间。你的其余代码在哪里?

标签: java timeout connect urlconnection


【解决方案1】:

试试这个:

       import java.net.HttpURLConnection;

       URL url = new URL("http://www.myurl.com/sample.xml");

       HttpURLConnection huc = (HttpURLConnection) url.openConnection();
       HttpURLConnection.setFollowRedirects(false);
       huc.setConnectTimeout(15 * 1000);
       huc.setRequestMethod("GET");
       huc.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 (.NET CLR 3.5.30729)");
       huc.connect();
       InputStream input = huc.getInputStream();

       import org.jsoup.nodes.Document;

       Document doc = null;
       try {
           doc = Jsoup.connect("http://www.myurl.com/sample.xml").get();
       } catch (Exception e) {
           //log error
       }

并看看如何使用Jsoup:http://jsoup.org/cookbook/input/load-document-from-url

【讨论】:

  • 使用 Java 7 (+) 时,它的工作方式与预期一样:conn.setReadTimeout(1000*10*1); conn.setConnectTimeout(1000*10*1); // 10 seks to wait for connection 等待连接和数据正好 10 秒。
  • 这只影响连接超时,不影响读取超时。不以任何方式回答问题。
【解决方案2】:

您可以通过线程睡眠手动强制断开连接。这是一个例子:

URLConnection con = url.openConnection();
con.setConnectTimeout(5000);
con.setReadTimeout(5000);
new Thread(new InterruptThread(con)).start();

然后

public class InterruptThread implements Runnable {

    HttpURLConnection con;
    public InterruptThread(HttpURLConnection con) {
        this.con = con;
    }

    public void run() {
        try {
            Thread.sleep(5000); // or Thread.sleep(con.getConnectTimeout())
        } catch (InterruptedException e) {

        }
        con.disconnect();
        System.out.println("Timer thread forcing to quit connection");
    }
}

【讨论】:

  • 来自文档:void java.net.HttpURLConnection.disconnect() 表示在不久的将来不太可能向服务器发出其他请求。调用 disconnect() 不应暗示此 HttpURLConnection 实例可用于其他请求。 --> 所以调用disconnect()的时候socket不一定是关闭的。
  • 请注意,此代码无论如何都会在 5 秒内尝试断开连接,即使您已成功连接并希望继续使用该连接。
【解决方案3】:

您可以通过更改以下系统属性为从 jvm 建立的所有连接设置超时:

System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
System.setProperty("sun.net.client.defaultReadTimeout", "10000");

每个连接都会在 10 秒后超时。

不需要设置'defaultReadTimeout',但如果您需要控制阅读,则作为示例显示。

【讨论】:

  • 这是我在 Windows 和 OSX 上运行所需要的
  • 仅适用于 HTTP。 java.net.Socket 不使用这些。
【解决方案4】:

我使用类似的代码从服务器下载日志。我调试了我的代码,发现返回的 URLConnection 的实现是 sun.net.www.protocol.http.HttpURLConnection。

抽象类 java.net.URLConnection 有两个属性 connectTimeout 和 readTimeout,setter 在抽象类中。信不信由你实现 sun.net.www.protocol.http.HttpURLConnection 具有相同的属性 connectTimeout 和 readTimeout 没有 setter 和来自实现类的属性用于 getInputStream 方法。所以设置 connectTimeout 和 readTimeout 是没有用的,因为它们从未在 getInputStream 方法中使用。在我看来,这是 sun.net.www.protocol.http.HttpURLConnection 实现中的错误。

我的解决方案是使用 HttpClient 和 Get 请求。

【讨论】:

【解决方案5】:

你在 Windows 上吗? Windows 上的底层套接字实现似乎不能很好地支持 SO_TIMEOUT 选项。另请参阅此答案:setSoTimeout on a client socket doesn't affect the socket

【讨论】:

  • 自 1992 年以来从未见过这种情况。此处或您的链接中均未提供任何证据。
猜你喜欢
  • 1970-01-01
  • 2014-04-07
  • 1970-01-01
  • 2013-05-23
  • 2019-02-27
  • 2015-03-23
  • 2015-12-20
  • 2014-11-21
  • 2014-03-08
相关资源
最近更新 更多