有一个私人网络服务器(支持https),我需要经常阅读/设置一些信息。我做了一些java代码自动完成。当我使用Chrome访问它时,第一个连接速度很慢(可能是5秒),但连续连接速度很快(大约1S)。使用我的java代码,每次都很慢。我知道问题是在与我的代码的每个连接中执行完整的TLS握手。我的问题是,Chrome做了什么来加快速度,我如何在我的代码中模拟它?以下是我的代码的一部分:
class MyTrust implements X509TrustManager{
public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}
public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}
public X509Certificate[] getAcceptedIssuers() {return null; }
}
并在另一个建立连接的类中:
URLConnection conn = (HttpsURLConnection) url.openConnection();
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, new TrustManager[] { new MyTrust() }, new java.security.SecureRandom());
((HttpsURLConnection) conn).setSSLSocketFactory(sc.getSocketFactory());
我正在阅读Java Secure Socket Extension (JSSE) Reference Guide,但发现它很难理解。 SessinID或Principal是否有效?谁能给我一些提示?
答案 0 :(得分:0)
您的Java代码每次都建立连接,因此每次都会执行TLS握手。
但是,如果服务器接受保持连接(通过返回Connection:Keep-Alive
标头,浏览器(例如Chrome)将尝试保持连接处于活动状态(通过在请求中添加Connection:Keep-Alive
标头)响应),大多数服务器都会这样做,浏览器会尝试在正在进行的请求中使用相同的连接,因此不需要每次都执行TLS握手。
对于您的Java代码,您可以将连接存储在池中,并重用它。您可以查看支持http连接池的Apache HttpComponents
从评论中编辑:
因为真正的问题是关于SSL / TLS会话重用不起作用。我怀疑它是由滥用JSSE引起的。您必须在每个连接上使用相同的SSLContext以启用会话重用。此外,由于连接上的一些错误操作(例如读取流的末尾),会话可能被丢弃。此处列出了一些详细信息:How to enable client TLS session reuse in Java