2017-10-08 129 views
1

在這段代碼中,我試圖讀取對本地主機服務器進行的不同連接的響應。 有趣的是,在我的代碼當InputStream結束而沒有明確的斷開連接時,HttpUrlConnection被關閉

  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的輸出很明顯,沒有任何連接。

回答

0

這是預期的行爲。

InputStream發送完成請求到服務器是否好,如果沒有額外的東西要接收?我沒有看到它的問題。

+0

這顯然是好的。但是我所見過的每一個文檔都明確指定關閉inputStream和HttpurlConnection。 –

+0

儘快釋放資源是件好事。否則,它將在稍後由垃圾收集器完成。 –

+0

正如我上面所說,釋放資源顯然是很好的。目前在我上面的摘錄中,它不是由GC完成的,因爲我在我的代碼中有一個Thread.Sleep,並且在此期間已經執行了tcpdump。 –

相關問題