HttpURLConnection实现

Cra*_*lus 17 java network-programming jdk1.6 httpurlconnection

我已经读过HttpURLConnection支持持久连接,因此可以为多个请求重用连接.我尝试了它,发送第二个POST的唯一方法是第二次调用openConnection.否则我得到一个IllegalStateException("已经连接"); 我使用了以下内容:

try{
URL url = new URL("http://someconection.com");
}
catch(Exception e){}
HttpURLConnection con = (HttpURLConnection) url.openConnection();
//set output, input etc
//send POST
//Receive response
//Read whole response
//close input stream
con.disconnect();//have also tested commenting this out
con = (HttpURLConnection) url.openConnection();
//Send new POST
Run Code Online (Sandbox Code Playgroud)

第二个请求是通过相同的TCP连接发送的(用wireshark验证它)但我无法理解为什么(虽然这是我想要的)因为我已经调用了disconnect.我检查了HttpURLConnection的源代码,并且实现确实保持了对相同目标的连接的keepalive缓存.我的问题是,在发送第一个请求后,我无法看到连接如何放回缓存中.断开连接关闭连接,没有断开连接,我仍然无法看到连接如何放回缓存.我看到缓存有一个run方法来遍历所有空闲连接(我不确定它是如何被调用的),但我找不到连接如何放回缓存中.似乎唯一发生的地方是httpClient的完成方法,但是没有调用带响应的POST.谁可以帮我这个事?

编辑 我的兴趣是,对于tcp连接重用,HttpUrlConnection对象的正确处理是什么.应该关闭输入/输出流,然后是url.openConnection(); 每次发送新请求(避免disconnect())?如果是,我第二次调用url.openConnection()时无法看到连接是如何重用的,因为第一个请求已从缓存中删除了连接,但无法找到返回的连接方式.是否有可能连接没有返回到keepalive缓存(bug?),但操作系统尚未发布tcp连接,在新连接上,OS返回缓冲连接(尚未发布)或类似的东西? EDIT2 我找到的唯一相关内容来自JDK_KeepAlive

...当应用程序在URLConnection.getInputStream()返回的InputStream上调用close()时,JDK的HTTP协议处理程序将尝试清理连接,如果成功,则将连接放入连接缓存以供将来的HTTP请求重用.

但我不确定这是哪个处理程序.sun.net.www.protocol.http.Handler没有做任何缓存,因为我看到谢谢!

use*_*421 17

应该关闭输入/输出流,然后是url.openConnection(); 每次发送新请求(避免disconnect())?

是.

如果是,我第二次调用url.openConnection()时无法看到连接是如何重用的,因为第一个请求已从缓存中删除了连接,但无法找到返回的连接方式.

你是混淆HttpURLConnection与底层Socket它的 TCP连接.他们不一样.该HttpURLConnection实例GC'd,底层Socket是汇集,除非你打电话disconnect().


Jim*_*son 7

来自HttpURLConnection的javadoc(我的重点):

每个HttpURLConnection实例用于发出单个请求,但是与HTTP服务器的基础网络连接可以由其他实例透明地共享.在请求之后调用HttpURLConnection的InputStream或OutputStream上的close()方法可以释放与此实例关联的网络资源,但不会影响任何共享持久连接.如果此时持久连接处于空闲状态,则调用disconnect()方法可能会关闭底层套接字.