我正在使用HttpClient
POST方法。我需要创建一次HttpClient
,并且应该使用Keep Alive Connection。但我认为在我的情况下,它每次都建立一个新的连接。
所以,我需要为HttpClient
使用 Keep Alive 连接。
这是我的代码片段,任何帮助都会得到很多赞赏。
ClientConnectionManager mgr = httpclient_recv.getConnectionManager();
hp = httpclient_recv.getParams();
httpclient_recv = new DefaultHttpClient(
new ThreadSafeClientConnManager(hp,mgr.getSchemeRegistry()), hp);
while (true) {
try {
java.util.logging.Logger.getLogger("org.apache.http.wire")
.setLevel(java.util.logging.Level.FINER);
java.util.logging.Logger.getLogger("org.apache.http.headers")
.setLevel(java.util.logging.Level.FINER);
System.setProperty("org.apache.commons.logging.Log",
"org.apache.commons.logging.impl.SimpleLog");
System.setProperty(
"org.apache.commons.logging.simplelog.showdatetime",
"true");
System.setProperty(
"org.apache.commons.logging.simplelog.log.httpclient.wire",
"debug");
System.setProperty(
"org.apache.commons.logging.simplelog.log.org.apache.http",
"debug");
System.setProperty(
"org.apache.commons.logging.simplelog.log.org.apache.http.headers",
"debug");
ByteArrayEntity bae = new ByteArrayEntity(byteData);
bae.setContentType(new BasicHeader(HTTP.CONTENT_TYPE,
"binary/octet-stream"));
httppost_recv.setHeader(HTTP.CONN_DIRECTIVE,HTTP.CONN_KEEP_ALIVE);
httppost_recv.setEntity(bae);
{
System.out.println("res b4 response");
response_recv = httpclient_recv
.execute(httppost_recv);
response_recv.getEntity().consumeContent();
System.out.println("res a4 response");
if (response_recv != null) {
byteArray = EntityUtils.toByteArray(response_recv
.getEntity());
playing = true;
}
}
}
以及logcat日志是:
12-03 10:07:29.466: I/System.out(1529): res b4 response
12-03 10:07:29.646: D/org.apache.http.wire(1529): >> "POST /ping HTTP/1.1[EOL]"
12-03 10:07:29.666: D/org.apache.http.wire(1529): >> "Connection: Keep-Alive[EOL]"
12-03 10:07:29.686: D/org.apache.http.wire(1529): >> "Content-Length: 1[EOL]"
12-03 10:07:29.705: D/org.apache.http.wire(1529): >> "Content-Type: binary/octet-stream[EOL]"
12-03 10:07:29.716: D/org.apache.http.wire(1529): >> "Host: 192.168.1.36[EOL]"
12-03 10:07:29.725: D/org.apache.http.wire(1529): >> "User-Agent: Apache-HttpClient/UNAVAILABLE (java 1.4)[EOL]"
12-03 10:07:29.736: D/org.apache.http.wire(1529): >> "[EOL]"
12-03 10:07:29.746: D/org.apache.http.headers(1529): >> POST /ping HTTP/1.1
12-03 10:07:29.746: D/org.apache.http.headers(1529): >> Connection: Keep-Alive
12-03 10:07:29.756: D/org.apache.http.headers(1529): >> Content-Length: 1
12-03 10:07:29.756: D/org.apache.http.headers(1529): >> Content-Type: binary/octet-stream
12-03 10:07:29.765: D/org.apache.http.headers(1529): >> Host: 192.168.1.36
12-03 10:07:29.765: D/org.apache.http.headers(1529): >> User-Agent: Apache-HttpClient/UNAVAILABLE (java 1.4)
12-03 10:07:29.776: D/org.apache.http.wire(1529): >> "[0x0]"
12-03 10:07:29.796: D/org.apache.http.wire(1529): << "HTTP/1.1 200 OK[EOL]"
12-03 10:07:29.805: D/org.apache.http.wire(1529): << "Server: gSOAP/2.8[EOL]"
12-03 10:07:29.816: D/org.apache.http.wire(1529): << "Content-Type: binary/octet-stream[EOL]"
12-03 10:07:29.826: D/org.apache.http.wire(1529): << "Content-Length: 2048[EOL]"
12-03 10:07:29.836: D/org.apache.http.wire(1529): << **"Connection: close[EOL]"**
12-03 10:07:29.887: D/org.apache.http.headers(1529): << HTTP/1.1 200 OK
12-03 10:07:29.896: D/org.apache.http.headers(1529): << Server: gSOAP/2.8
12-03 10:07:29.896: D/org.apache.http.headers(1529): << Content-Type: binary/octet-stream
12-03 10:07:29.906: D/org.apache.http.headers(1529): << Content-Length: 2048
12-03 10:07:29.906: D/org.apache.http.headers(1529): << **Connection: close**
12-03 10:07:29.916: I/System.out(1529): res a4 response
答案 0 :(得分:8)
10:07:29.746:D / org.apache.http.headers(1529):&gt;&gt;连接:Keep-Alive
您正在请求keepalive。
10:07:29.836:D / org.apache.http.wire(1529):&lt;&lt; “连接:关闭[EOL]”
服务器拒绝它。
你最终无法做到这一点。
答案 1 :(得分:3)
从HTTP 1.1开始,默认情况下启用keep-alive。如果您不希望在处理HTTP 1.1时明确重用连接,则需要关闭连接。
对于1.0,标题就是你为此设置的标题&#34; Connection:Keep-alive&#34; 这只会暗示您要重用连接的服务器。当处于压力或其他原因时,服务器可能会选择采取不同的行动,如下所述。
对于大多数用途,这里的大多数答案都是正确的,在哪里添加keep alive标头并且效果很好。以下说明适用于您执行此操作但仍无效的情况。
通常,当服务器正常运行时,答案将集中在设置上,但这并非完全正确。服务器(如Rudra)构建为在不同情况下表现不同。保持活动状态伴随着服务器在断开连接之前为您提供的许多请求,这也是为了向其他人提供服务,因此在高负载的情况下,某些服务器可能会采取减少保持活动请求的数量为每个新连接服务。
从上次收到的请求中还有一个超时设置,如果在该时间窗口中没有进一步的请求,最终会导致断开连接。很少有现代服务器可以根据他们目前的容量改变这一点,或者在恐慌情况下将其降低到0,使得保持活力毫无意义。因此,如果您尝试连接的服务器遇到任何此类(竞赛,恐慌)情况,它可能会选择放弃您的请求。
出于文档目的。 来自hc.apache.org:
HttpClient始终尽力重用连接。连接 默认情况下启用持久性,无需配置。下 在某些情况下,这可能导致连接泄漏,从而丢失 资源。禁用连接持久性的最简单方法是 提供或扩展强制关闭连接的连接管理器 在releaseConnection方法中发布。
HttpClient提供了这些(读取:琐碎的)开箱即用的东西。但是,Apache还提供了其他可以添加的功能,以提高它的性能。
例如,可以为HttpClient定制ConnectionManager。
因此,可以阻止保持活动/连接持久性的事情是您可能正在使用的连接管理器(在您的情况下这不是真的,但在其他几种情况下可能也是如此)。如果您从某个API获取Client对象以进行调用,那么这可能是一个完全未知/抽象的事实。下面列出了一个如何自定义的示例(来自Apache连接管理文档)
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
// Increase max total connection to 200
cm.setMaxTotal(200);
// Increase default max connection per route to 20
cm.setDefaultMaxPerRoute(20);
// Increase max connections for localhost:80 to 50
HttpHost localhost = new HttpHost("locahost", 80);
cm.setMaxPerRoute(new HttpRoute(localhost), 50);
CloseableHttpClient httpClient = HttpClients.custom()
.setConnectionManager(cm)
.build();
(有关详细信息,请参阅Apache documentation on connection management)
如果遇到此问题,请在没有CM的情况下试用或创建自己的HttpClient对象。也没有必要将CM用于多个连接。内置的CM足够公平。如果您发现性能下降,可以编写自己的连接管理器。
然而,在你的情况下,你的服务器不是非常支持它可能根本不尊重Keep-alive,即使你有那些标题,什么不是。您需要检查超时标头作为响应,在向服务器发送新请求时发送保持活动以确定服务器是否投诉。
答案 2 :(得分:0)
为什么不用你所有的请求使用同一个客户端???
我一直在开发一个需要向很多网络服务请求大量数据的应用程序,为此我只使用一个静态客户端并且工作正常!
我创建了一个返回HttpClient的类和另一个管理我所有请求的类(POST和GET),很简单;)