11

我正在HttpClient使用 POST 方法。我需要创建HttpClient一次并且应该使用 Keep Alive Connection。但我认为在我的情况下,它每次都建立一个新的连接。

所以,我需要使用Keep Alive连接HttpClient

这是我的代码片段,任何帮助将不胜感激。

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
4

3 回答 3

10

10:07:29.746: D/org.apache.http.headers(1529): >> 连接: Keep-Alive

您正在请求保活。

10:07:29.836:D/org.apache.http.wire(1529):<< “连接:关闭 [EOL]”

服务器拒绝它。

你最终无能为力。

于 2012-12-03T04:49:55.113 回答
6

从 HTTP 1.1 开始,默认情况下启用 keep-alive。如果您不希望在处理 HTTP 1.1 时显式重用它,则需要关闭连接。

对于 1.0,标头是您为此“连接:保持活动”设置的内容,这只会提示您要重用连接的服务器。当处于压力之下或出于其他原因时,服务器可能会选择不同的行为,如下所述。

对于大多数目的,这里的大多数答案都是正确的,在其中添加保持活动标题并且效果很好。以下说明适用于您执行此操作但仍然不起作用的情况。


服务器端问题

通常,当服务器正常运行时,答案将集中在设置上,但这并不完全正确。服务器(如Rudra)被构建为在不同情况下表现不同。Keep-alive 附带了许多请求,服务器会在断开连接之前为您提供服务,这也是为了允许为其他人提供服务,因此在高负载的情况下,某些服务器可能会诉诸于减少 keep-alive 请求的数量为每个新连接服务。

还从收到的最后一个请求设置了超时,如果在该时间窗口内没有进一步的请求,最终将导致断开连接。很少有现代服务器可能会根据它们目前的容量来改变这一点,或者在恐慌情况下将其降至 0,从而使保持活动变得毫无意义。因此,如果您尝试连接的服务器正在经历任何此类(竞争、恐慌)情况,它可能会选择丢弃您的请求。


客户端问题

出于文档目的。来自hc.apache.org

HttpClient 总是尽最大努力重用连接。默认情况下启用连接持久性,无需配置。在某些情况下,这可能会导致连接泄漏,从而导致资源丢失。禁用连接持久性的最简单方法是提供或扩展一个连接管理器,该管理器在 releaseConnection 方法中释放时强制关闭连接。

HttpClient 提供了这些(阅读:琐碎的)开箱即用的东西。但是 Apache 还提供了其他一些东西,您可以添加它们来提高它的性能。

例如,可以为 HttpClient 定制 ConnectionManager(s)。

因此,可以阻止保持活动/连接持久性的是您可能正在使用的连接管理器(在您的情况下这不是真的,但在其他几种情况下可能是真的)。如果您正在获取客户端对象以从某些 API 进行调用,这对您来说可能是一个完全未知/抽象的事实。下面列出了如何自定义的示例(来自 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 文档)

如果您遇到此问题,请尝试不使用 CM 或创建您自己的 HttpClient 对象。也不必为多个连接使用 CM。内置的CM足够公平。如果您看到性能损失,您可以编写自己的连接管理器。

但是,在您的情况下,您的服务器不是很支持它可能根本不支持 Keep-alive,即使您有这些标头而没有。您需要检查超时标头作为响应,在向服务器发送新请求中的 keep-alive 以建立该服务器是投诉的。

于 2016-05-31T02:26:17.197 回答
0

你为什么不对所有请求使用同一个客户端???

我一直在开发一个需要向许多 Web 服务请求大量数据的应用程序,为此我只使用一个静态客户端并且工作完美!

我创建了一个返回 HttpClient 的类和另一个管理我的所有请求(POST 和 GET)的类,既简单又方便;)

于 2015-04-01T00:55:43.823 回答