【问题标题】:HttpUrlConnection gets Closed when InputStream Ends without explicit disconnect当 InputStream 在没有明确断开连接的情况下结束时,HttpUrlConnection 会关闭
【发布时间】:2017-10-08 07:32:38
【问题描述】:

在这段代码中,我试图从与 localhost 服务器建立的不同连接中读取响应。 有趣的是,在我的代码中

  1. 阅读整个 inputStream 后,连接会自动断开或释放资源
  2. 连接不会自动断开,我们必须明确关闭连接,以防我们没有读取整个 inputStream。这是意料之中的

此代码是否会出现这种 (1) 行为,如果是,那么为什么?

这是客户端的代码:

public class UrlConnectionHttpClient {

    static List<InputStream> list = new ArrayList<InputStream>();

    public static void main(String[] args) throws InterruptedException {
        System.out.println("time " + System.currentTimeMillis());
        for(int i = 0; i < 5; i++) {
            call(i);
        }
    }

    private static void read(InputStream in) throws IOException {
        while (true) {
            Integer a = in.read();
            if (a == -1) {
                return;
            }
        }
    }

    static Thread call(final int i) throws InterruptedException {
        Thread t = new Thread(new Runnable() {
            public void run() {
                try {
                    long t1 = System.currentTimeMillis();
                    URL l = new URL("http://localhost:8020/?q=" + i);
                    HttpURLConnection connection = (HttpURLConnection) l.openConnection();
                    System.out.println("starting to execute + " + i);
                    connection.setRequestMethod("POST");
                    connection.setReadTimeout(1000 * 1000);
                    connection.setConnectTimeout(5 * 1000);
                    connection.setRequestProperty("Accept", "avro/binary");
                    connection.setDoOutput(true);
                    InputStream inputStream = connection.getInputStream();
                    read(inputStream);
                    //inputStream.close();
                    //connection.disconnect();
                    //list.add(connection.getInputStream());
                    long t2 = System.currentTimeMillis();
                    //System.out.println("finished to execute + " + i + " and time taken is: " + (t2 - ti) + " time is: " +  System.currentTimeMillis() + " and size is: " + list.size());
                    Thread.sleep(100000);
                    } catch (ProtocolException e) {
                        e.printStackTrace();
                    } catch (MalformedURLException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
            }
        });
        t.start();
        return t;
    }
}

`

这是服务器上端口的 tcpdump 输出。 从 tcpdump 中我们可以清楚地看到 localhost 服务器正在接收 fin 数据包。

12:26:46.079516 IP localhost.54880 > localhost.intu-ec-svcdisc: Flags [.], ack 65, win 12757, options [nop,nop,TS val 429721894 ecr 429721894], length 0
12:26:46.079527 IP localhost.54880 > localhost.intu-ec-svcdisc: Flags [.], ack 9887, win 12450, options [nop,nop,TS val 429721894 ecr 429721894], length 0
12:26:56.092276 IP localhost.54879 > localhost.intu-ec-svcdisc: Flags [F.], seq 119, ack 9887, win 12450, options [nop,nop,TS val 429731883 ecr 429721893], length 0
12:26:56.092318 IP localhost.54881 > localhost.intu-ec-svcdisc: Flags [F.], seq 119, ack 9887, win 12450, options [nop,nop,TS val 429731883 ecr 429721893], length 0
12:26:56.092333 IP localhost.54878 > localhost.intu-ec-svcdisc: Flags [F.], seq 119, ack 9887, win 12450, options [nop,nop,TS val 429731883 ecr 429721894], length 0
12:26:56.092339 IP localhost.intu-ec-svcdisc > localhost.54879: Flags [.], ack 120, win 12755, options [nop,nop,TS val 429731883 ecr 429731883], length 0
12:26:56.092350 IP localhost.54877 > localhost.intu-ec-svcdisc: Flags [F.], seq 119, ack 9887, win 12450, options [nop,nop,TS val 429731883 ecr 429721893], length 0
12:26:56.092353 IP localhost.intu-ec-svcdisc > localhost.54881: Flags [.], ack 120, win 12755, options [nop,nop,TS val 429731883 ecr 429731883], length 0
12:26:56.092362 IP localhost.intu-ec-svcdisc > localhost.54878: Flags [.], ack 120, win 12755, options [nop,nop,TS val 429731883 ecr 429731883], length 0
12:26:56.092363 IP localhost.54880 > localhost.intu-ec-svcdisc: Flags [F.], seq 119, ack 9887, win 12450, options [nop,nop,TS val 429731883 ecr 429721894], length 0
12:26:56.092379 IP localhost.intu-ec-svcdisc > localhost.54877: Flags [.], ack 120, win 12755, options [nop,nop,TS val 429731883 ecr 429731883], length 0
12:26:56.092390 IP localhost.intu-ec-svcdisc > localhost.54880: Flags [.], ack 120, win 12755, options [nop,nop,TS val 429731883 ecr 429731883], length 0
12:26:56.094884 IP localhost.intu-ec-svcdisc > localhost.54877: Flags [F.], seq 9887, ack 120, win 12755, options [nop,nop,TS val 429731885 ecr 429731883], length 0
12:26:56.095051 IP localhost.54877 > localhost.intu-ec-svcdisc: Flags [.], ack 9888, win 12450, options [nop,nop,TS val 429731885 ecr 429731885], length 0
12:26:56.095483 IP localhost.intu-ec-svcdisc > localhost.54878: Flags [F.], seq 9887, ack 120, win 12755, options [nop,nop,TS val 429731885 ecr 429731883], length 0
12:26:56.095561 IP localhost.54878 > localhost.intu-ec-svcdisc: Flags [.], ack 9888, win 12450, options [nop,nop,TS val 429731885 ecr 429731885], length 0
12:26:56.095935 IP localhost.intu-ec-svcdisc > localhost.54881: Flags [F.], seq 9887, ack 120, win 12755, options [nop,nop,TS val 429731886 ecr 429731883], length 0
12:26:56.095984 IP localhost.54881 > localhost.intu-ec-svcdisc: Flags [.], ack 9888, win 12450, options [nop,nop,TS val 429731886 ecr 429731886], length 0
12:26:56.096413 IP localhost.intu-ec-svcdisc > localhost.54879: Flags [F.], seq 9887, ack 120, win 12755, options [nop,nop,TS val 429731886 ecr 429731883], length 0
12:26:56.096474 IP localhost.54879 > localhost.intu-ec-svcdisc: Flags [.], ack 9888, win 12450, options [nop,nop,TS val 429731886 ecr 429731886], length 0
12:26:56.096873 IP localhost.intu-ec-svcdisc > localhost.54880: Flags [F.], seq 9887, ack 120, win 12755, options [nop,nop,TS val 429731886 ecr 429731883], length 0
12:26:56.096936 IP localhost.54880 > localhost.intu-ec-svcdisc: Flags [.], ack 9888, win 12450, options [nop,nop,TS val 429731886 ecr 429731886], length 0

同样从 lsof 输出中可以清楚地看出没有连接。

【问题讨论】:

    标签: java httpurlconnection


    【解决方案1】:

    这是预期的行为。

    InputStream 如果没有任何额外的东西要接收,向服务器发送完成请求不是很好吗?我看不出有什么问题。

    【讨论】:

    • 显然不错。但是我看到的每个文档都指定明确关闭 inputStream 和 HttpurlConnection。
    • 尽快释放资源是好事。否则垃圾收集器会在稍后完成。
    • 正如我上面所说,释放资源显然是件好事。目前在我上面的摘录中它没有被 GC 完成,因为我的代码中有一个 Thread.Sleep 并且在此期间已经使用了 tcpdump。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-18
    • 2018-09-14
    • 2013-02-27
    • 1970-01-01
    • 2018-02-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多