Http Client 4.5不使用Java

时间:2015-09-28 09:30:58

标签: java tcp

我的下面的代码是使用apache http client 4.5版本的池连接管理器。如果我发出50个请求,我在netstat中看到正在使用50个不同的tcp端口,但是最多使用5个连接时间。我在wire shark中也看到过滤器tcp.flags.syn==1 && tcp.flags.ack==0它在过滤器中创建了50个包,所以它使用不同的连接而不是使用相同的连接,所以为什么我不能这样做?

我的代码:

import javax.net.ssl.SSLContext;

import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;
import org.glassfish.jersey.SslConfigurator;
import org.json.JSONException;
import org.json.JSONObject;

public class App3Conn {
    private static CloseableHttpClient client;


    static String target="https://example.com";

    static PoolingHttpClientConnectionManager cm ;
static{

SslConfigurator sslConfig = SslConfigurator.newInstance()
            .securityProtocol("TLS")
            .keyStoreFile("/Users/file")
            .keyStorePassword("passw")
            .keyStoreType("JKS")
            .trustStoreFile("/Users/file");

    SSLContext sslCtx = sslConfig.createSSLContext();
    SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslCtx,NoopHostnameVerifier.INSTANCE);
    Registry<ConnectionSocketFactory> r = RegistryBuilder.<ConnectionSocketFactory>create()
            .register("http", PlainConnectionSocketFactory.getSocketFactory())
            .register("https", sslsf)
            .build();


    cm = new PoolingHttpClientConnectionManager(r);
    cm.setMaxTotal(15);
    cm.setDefaultMaxPerRoute(5);

    client = HttpClients.custom().setSSLSocketFactory(sslsf).setConnectionManager(cm).build();


}
public static void main(String a[]) throws JSONException, ClientProtocolException, IOException
{

    JSONObject jsonMessage = new JSONObject();



    JSONObject jsonResponse;

    jsonMessage.put("keyID", "keyID" );


     StringEntity se = new StringEntity(jsonMessage.toString());
     CloseableHttpResponse response2;
    HttpPost httpPost = new HttpPost(target);
    httpPost.setEntity(se);
    httpPost.setHeader("Accept", "application/json");
    httpPost.setHeader("Content-type", "application/json");
    httpPost.setHeader("Connection", "keep-alive");
    int i;
    for(i=0;i<50;i++)
    {

        response2 = client.execute(httpPost);


     HttpEntity entity2 = response2.getEntity();
     String result = EntityUtils.toString(entity2);

     EntityUtils.consume(entity2);


     jsonResponse = new JSONObject(result);

    String text = jsonResponse.getString("result");


    response2.close();
    }
}
}

2 个答案:

答案 0 :(得分:2)

我以前见过这个。这取决于Apache连接池的工作方式。不透明的state成员与池条目相关联,并且在请求(租用)池条目时必须与请求的状态匹配。

当进行连接租约尝试时,请求的statenull。但是,当将连接放回池中时,state将设置为SSL对等方的X500Principal对象。这发生在DefaultUserTokenHandler类中。幸运的是,当我们创建HttpClient类时,这是可以覆盖的。这是一个例子:

HttpClient apacheHttpClient = HttpClients.custom()
    .setConnectionReuseStrategy(new DefaultConnectionReuseStrategy())
    .setConnectionManager(new PoolingHttpClientConnectionManager(r))
    .setUserTokenHandler(new UserTokenHandler() {
      @Override
      public Object getUserToken(HttpContext context) {
        return null;
      }
    })
    .build();

如果您创建的DefaultUserTokenHandler可以通过HttpClient连接到多个SSL对等方,请检查您是否从RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . index.php 丢失了您所依赖的任何内容,并且不要使用此方法相同的HTTP路由。在我的情况下,此客户端用于连接到单个SSL服务器。

答案 1 :(得分:0)

要重用池连接时,请不要关闭响应。 无需response2.close(); response.close()关闭所有输入/输出资源,最后关闭tcp连接(套接字)。