HttpsUrlConnection and Keep-alive

2022-09-01 09:03:58

我正在我目前的项目中使用处理客户端身份验证等。目前,它只打印出客户端地址/端口,以便我可以检查一个TCP连接是否用于多个请求()或者是否为每个请求建立了新的连接(因此每次都进行新的SSL握手)。当我使用FireFox对服务器发出多个请求时,我可以看到keep-alive正在工作。因此,服务器部分可以很好地处理GET和POST请求。com.sun.net.httpserver.HttpsServerkeep-alive

如果我用于对服务器发出请求(在本例中不使用SSL),也可以工作:只有一个连接为多个顺序启动的请求建立。HttpURLConnectionkeep-alive

但是,如果我使用(使用完全相同的代码,但使用SSL)则不再有效。因此,对于每个请求,都会建立一个新连接,尽管我使用相同的(和):HttpsURLConnectionkeep-aliveSSLContextSSLSocketFactory

// URL myUrl = ...
// SSLContext mySsl = ...
HttpsURLConnection conn = (HttpsURLConnection) myUrl.openConnection();
conn.setUseCaches(false);
conn.setSSLSocketFactory(mySsl.getSocketFactory());

conn.setRequestMethod("POST");
// send Data
// receive Data

我如何强制使用,因为许多请求会导致许多SSL握手,这是一个真正的性能问题?HttpsURLConnectionkeep-alive

更新(2012-04-02):我没有每次都调用,而是尝试缓存.但一切都没有改变。问题仍然存在。mySsl.getSocketFactory()SSLSocketFactory


答案 1

我遇到了同样的问题,经过一些深入的调试,终于有了解决方案。

默认情况下,Http(s)UrlConnection确实处理Keep-Alive,但套接字必须处于非常特定的条件下才能被重用。

这些是:

  • 输入流必须完全使用。您必须对输入流调用 read,直到它返回 -1 并关闭它。
  • 基础套接字上的设置必须使用完全相同的对象。
  • 完成操作后,您应该在Http(s)URLConnection上调用断开连接(是的,这是违反直觉的)。

在上面的代码中,问题是:

conn.setSSLSocketFactory(mySsl.getSocketFactory());

在初始化期间将 getSocketFactory() 的结果保存到静态变量,然后将其传递到 conn.setSSLSocketFactory 应该允许重用套接字。


答案 2

我无法让它与.但是Apache的HTTP客户端很好地处理了SSL连接保持活动状态。HttpsUrlConnection