HttpURLConnection 实现
我读过 HttpURLConnection 支持持久连接,因此一个连接可以被多个请求重用.我试过了,发送第二个 POST 的唯一方法是第二次调用 openConnection.否则我得到一个 IllegalStateException("Already connected");我使用了以下内容:
I have read that HttpURLConnection supports persistent connections, so that a connection can be reused for multiple requests. I tried it and the only way to send a second POST was by calling openConnection for a second time. Otherwise I got a IllegalStateException("Already connected"); I used the following:
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
第二个请求是通过同一个 TCP 连接发送的(用wireshark 验证)但我不明白为什么(尽管这是我想要的),因为我调用了断开连接.我检查了 HttpURLConnection 的源代码,并且该实现确实保留了到相同目的地的连接的保活缓存.我的问题是,在我发送第一个请求后,我看不到连接是如何放回缓存中的.断开连接关闭连接并且没有断开连接,我仍然看不到连接是如何放回缓存中的.我看到缓存有一个运行方法来遍历所有空闲连接(我不确定它是如何调用的),但我找不到连接是如何放回缓存中的.似乎发生的唯一地方是在 httpClient 的完成方法中,但这不是为带有响应的 POST 调用的.谁能帮我解决这个问题?
The second request is send over the same TCP connection (verified it with wireshark) but I can not understand why (although this is what I want) since I have called disconnect. I checked the source code for the HttpURLConnection and the implementation does keep a keepalive cache of connections to the same destinations. My problem is that I can not see how the connection is placed back in the cache after I have send the first request. The disconnect closes the connection and without the disconnect, still I can not see how the connection is placed back in the cache. I saw that the cache has a run method to go through over all idle connections (I am not sure how it is called), but I can not find how the connection is placed back in the cache. The only place that seems to happen is in the finished method of httpClient but this is not called for a POST with a response. Can anyone help me on this?
编辑我的兴趣是,什么是 HttpUrlConnection 对象的正确处理以进行 tcp 连接重用.应该关闭输入/输出流,然后是 url.openConnection();每次发送新请求(避免断开())?如果是,当我第二次调用 url.openConnection() 时,我看不到连接是如何被重用的,因为连接已经从缓存中删除,因为第一个请求并且找不到它是如何返回的.连接是否有可能没有返回到keepalive缓存(错误?),但操作系统尚未释放tcp连接并且在新连接上,操作系统返回缓冲连接(尚未释放)或类似的东西?EDIT2我发现的唯一相关来自 JDK_KeepAlive
EDIT My interest is, what is the proper handling of an HttpUrlConnection object for tcp connection reuse. Should input/output stream be closed followed by a url.openConnection(); each time to send the new request (avoiding disconnect())? If yes, I can not see how the connection is being reused when I call url.openConnection() for the second time, since the connection has been removed from the cache for the first request and can not find how it is returned back. Is it possible that the connection is not returned back to the keepalive cache (bug?), but the OS has not released the tcp connection yet and on new connection, the OS returns the buffered connection (not yet released) or something similar? EDIT2 The only related i found was from JDK_KeepAlive
...当应用程序调用 close()在由返回的 InputStream 上URLConnection.getInputStream(),JDK 的 HTTP 协议处理程序将尝试清理连接,如果成功,把连接放到一个供未来重用的连接缓存HTTP 请求.
...when the application calls close() on the InputStream returned by URLConnection.getInputStream(), the JDK's HTTP protocol handler will try to clean up the connection and if successful, put the connection into a connection cache for reuse by future HTTP requests.
但我不确定这是哪个处理程序.sun.net.www.protocol.http.Handler 没有像我看到的那样做任何缓存谢谢!
But I am not sure which handler is this. sun.net.www.protocol.http.Handler does not do any caching as I saw Thanks!
推荐答案
是否应该关闭输入/输出流后跟一个 url.openConnection();每次发送新请求(避免断开连接())?
Should input/output stream be closed followed by a url.openConnection(); each time to send the new request (avoiding disconnect())?
是的.
如果是,我看不到连接情况如何我打电话时重复使用url.openConnection() 第二个时间,因为连接已经第一次从缓存中删除请求,但找不到它是怎么回事回来了.
If yes, I can not see how the connection is being reused when I call url.openConnection() for the second time, since the connection has been removed from the cache for the first request and can not find how it is returned back.
您将 HttpURLConnection
与底层 Socket
和 its 底层 TCP 连接混淆了.他们不一样.HttpURLConnection
实例是 GC'd,底层 Socket
是池化的,除非你调用 disconnect().
You are confusing the HttpURLConnection
with the underlying Socket
and its underlying TCP connection. They aren't the same. The HttpURLConnection
instances are GC'd, the underlying Socket
is pooled, unless you call disconnect().
相关文章