Java HttpURLConnection和pooling

时间:2016-02-04 18:36:42

标签: java sockets tcp

在阅读了有关Java HttpURLConnection的所有类型的文档后,我仍然感到很困惑,因为它有什么样的集合以及如何进行连接。

例如,以下代码

URL url = new URL(someUrl);
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
OutputStream os = connection.getOutputStream();
InputStream is = connection.getInputStream();

/** Write something to os and flush */
/** Read from is */

os.close();
is.close();
connection.disconnect();
  1. 是否需要刷新并关闭osis以使底层套接字可重用?

  2. connection.disconnect()关闭底层套接字(从而使其无法使用)? keep-alive是否会影响此行为?

  3. 如果我使用不同的URL对象,但使用相同的URL,那么从它们创建的connection是否会共享底层套接字?如果URL的主机部分相同但路径不同,那该怎么办?

  4. 何时会破坏合并连接?

  5. 控制池大小的系统属性是什么?

  6. 此外,如果您还可以将Android版本与Java进行比较,那就太棒了。

    由于

2 个答案:

答案 0 :(得分:6)

  
      
  1. 是否需要刷新并关闭osis以使底层套接字可重用?
  2.   

关闭输入流就足够了。您无法刷新输入流,并且在关闭之前刷新输出流是多余的。

  
      
  1. connection.disconnect()关闭底层套接字(从而使其无法使用)?
  2.   

它可以作为关闭基础连接的提示。

  

keep-alive是否会影响此行为?

是。如果不存在,则必须关闭连接。

  
      
  1. 如果我使用不同的URL对象,但使用相同的URL,那么从它们创建的connection是否会共享底层套接字?
  2.   

  

当URL的主机部分相同但路径不同时,该怎么办?

  
      
  1. 何时会破坏合并连接?
  2.   

空闲超时后。

  
      
  1. 控制池大小的系统属性是什么?
  2.   

我不知道有一个,但如果有,它将在网络属性页面中定义,您可以通过Javadoc找到它。

  

此外,如果您还可以将Android版本与Java进行比较,那就太棒了。

我认为Android根本不会进行池化,但是当它们切换到OpenJDK源时,这应该会改变。

答案 1 :(得分:0)

实际上,接受的答案根本不适用于Android:

  1. Android会忽略http.keepAlive和http.maxConnections系统属性,因为网络代码会在静态初始化期间(即在进程/ JVM创建期间读取这些属性,而不是稍后检查它们是否更改)。参见https://code.google.com/archive/p/android-developer-preview/issues/2578

  2. 此评论不正确,因为Android确实支持连接池(有关更多详细信息,请参阅下一项):

      

    我认为Android根本不做池化,但这应该   切换到OpenJDK源时进行更改。

  3. OkHttp中实现的连接池(这是Android的HttpUrlConnection类下的实现)将计数视为所有服务器上的全局限制 (默认值为5)。这实际上是一个错误,与标准Java实现不匹配。参见https://github.com/square/okhttp/issues/1843

我在尝试禁用连接池时遇到了这种情况,结果发现两者都没有任何作用(也已与Android O确认)。取而代之的是,Android / OkHttp将一贯重复使用先前HTTP请求中剩下的5个连接。