我有两个Tomcat服务器需要维持持久连接以减少SSL握手.一台服务器(代理)位于DMZ中,而另一台服务器安全地位于另一台防火墙后面.代理基本上只运行一个简单的servlet,在将请求转发到安全机器之前进行一些健全性检查.在初始请求中,机器在执行实际工作之前交换证书.因此,我希望在几分钟的超时时间内保持持久连接.
要与安全服务器通信,代理上的servlet使用HttpsUrlConnection.我已经设置了WireShark,我注意到无论keepAliveTimeout我在安全机器上为连接器设置了什么值,TCP连接在大约5或10秒后关闭.这个数字似乎与我所读到的是默认超时以及Java如何处理HTTP Keep-Alive.此链接说明Java Keep-Alive如果服务器发送超时则表示超时,否则在关闭连接之前使用5秒(直接连接)或10秒(代理连接).
我想弄清楚的是如何强制Tomcat发送Keep-Alive标头.不Connection: Keep-Alive,但是Keep-Alive: timeout=x.
我已经尝试过Apache HTTP服务器并修改keepAliveTimeouthttpd.conf确实会导致Keep-Alive标头更改其超时值.此外,Java确实遵守此超时.
更新(12/23/11):在运行了几个实验之后,我尝试使用Apache的HttpClient(3.1)而不是使用Apache的HttpClient(3.1)来编写一些快速而脏的代码HttpsUrlConnection.看来HttpClient在设置为使用Keep-Alive时,只是等待服务器关闭连接.我不知道它会等多久.我正在拍摄以保持HTTP连接活动3到5分钟.
我正在尝试使用HttpsURLConnection我自己的信任管理器设置SSL(使用SSL恢复).
我只能进行ssl握手和连接.没有SSL恢复 - 之前的会话永远不会被重用!
我搜索了一遍,但没有运气.所有答案都是指HttpClient(不是一个选项).
我的设置如下:
我创建了一个SSL上下文,我将其存储供以后使用.
然后我使用这个SSL上下文创建一个SSL工厂,我也存储它以便与所有连接一起使用.
我开始一切顺利的连接:我收到一个sessionID,完成握手完成并将连接发送到服务器.
sessionID我之前的情况.我打印SSLContext的会话 - 最后一个会话仍在那里并且有效.由于某种原因,此新连接不使用它,因此会创建另一个会话并将其添加到会话的缓存中.我在两个不同的设备上尝试了Android版本2.3和4.1.
在许多谷歌搜索结果之后,我甚至试图像一些用户提议的那样添加Keep-Alive,以及导致没有不同结果的其他伏都教.
有没有人碰到这个?有什么我想念的吗?
什么可能导致我的连接不使用上一个会话?
提前致谢!
我在使用HttpClient在Android上恢复SSL会话时遇到了很多困难.
我每隔90秒轮询一次服务器(仅适用于只有一个功能的工业设备),所以我需要恢复会话,否则数据使用从每小时几KB到最高150-200kB,这是不可持续的.服务器是在Restlet中嵌入Jetty,并且当我使用OpenSSL测试它时支持恢复SSL会话.据我所知.
我正在重用我的HttpClient对象,所以不是这样.Android有一个特定的SSLCertificateSocketFactory,我也尝试过,它似乎也没有用.
有什么我在这里完全失踪的吗?我曾经假设HttpClient会自动执行此操作,我不确定我做错了什么,互联网上的任何人似乎都没有遇到类似的问题.
我通过以下方式设置了httpClient:
public HttpClient getNewHttpClient(Context context) {
try {
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
HttpConnectionParams.setStaleCheckingEnabled(params, false);
HttpConnectionParams.setConnectionTimeout(params, 4 * 1000);
HttpConnectionParams.setSoTimeout(params, 5 * 1000);
HttpConnectionParams.setSocketBufferSize(params, 8192);
HttpClientParams.setRedirecting(params, false);
SSLSessionCache sslSession = new SSLSessionCache(context);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
registry.register(new Scheme("https", SSLCertificateSocketFactory.getHttpSocketFactory(10*60*1000, sslSession), 444));
//registry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 444));
ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
return new DelegateHttpClient(ccm, params);
} catch (Exception e) {
return new DefaultHttpClient();
}
}
private static …Run Code Online (Sandbox Code Playgroud) 我编写了一个Java客户端应用程序,它使用客户端证书通过HTTPS连接到Apache Web服务器,并对服务器执行文件的HTTP PUT.它适用于小文件,但与大文件崩溃.
Apache服务器日志显示以下内容:
...
OpenSSL: Handshake: done
...
Changed client verification type will force renegotiation
...
filling buffer, max size 131072 bytes
...
request body exceeds maximum size (131072) for SSL buffer
could not buffer message body to allow SSL renegotiation to proceed
...
OpenSSL: I/O error, 5 bytes expected to read on BIO
(104)Connection reset by peer: SSL input filter read failed.
(32)Broken pipe: core_output_filter: writing data to the network
Connection closed to child 20 with standard shutdown …Run Code Online (Sandbox Code Playgroud) ssl ×3
android ×2
java ×2
apache ×1
httpclient ×1
https ×1
jsse ×1
keep-alive ×1
reusability ×1
session ×1
tomcat ×1