Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android HttpClient的SSL连接重用_Android_Ssl_Httpclient - Fatal编程技术网

Android HttpClient的SSL连接重用

Android HttpClient的SSL连接重用,android,ssl,httpclient,Android,Ssl,Httpclient,我正在自己实现的JavaWeb代理(将请求转发到实际的web服务)和android应用程序之间开发一个安全的web服务 使用标准(不安全的)http连接这样做效果很好。现在我想在代理和android客户端之间使用安全(SSL)连接 只要我为每个请求实例化一个新的HttpClient,这就可以工作,这不仅浪费了资源,而且速度非常慢,因为我正在为每个请求进行双向握手 因此,我试图为每个请求重用HttpClient,这将导致以下异常中的安全连接 java.lang.IllegalStateExcept

我正在自己实现的JavaWeb代理(将请求转发到实际的web服务)和android应用程序之间开发一个安全的web服务

使用标准(不安全的)http连接这样做效果很好。现在我想在代理和android客户端之间使用安全(SSL)连接

只要我为每个请求实例化一个新的HttpClient,这就可以工作,这不仅浪费了资源,而且速度非常慢,因为我正在为每个请求进行双向握手

因此,我试图为每个请求重用HttpClient,这将导致以下异常中的安全连接

java.lang.IllegalStateException:连接已打开。 位于org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:150) 位于org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119) 位于org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360) 位于org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555) 位于org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487) 位于org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)

当我将代理和客户端更改为无ssl通信时,它可以正常工作。 有人知道我做错了什么吗?非常感谢你的帮助

顺便说一句,服务器代码完全相似,只是使用带有加载证书的SSLServerSocket而不是使用ServerSocket

客户端参数设置

// Set basic data
    HttpParams params = new BasicHttpParams();
    HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
    HttpProtocolParams.setContentCharset(params, "UTF-8");
    HttpProtocolParams.setUseExpectContinue(params, true);
    HttpProtocolParams.setUserAgent(params, "Android app/1.0.0");

    // Make pool
    ConnPerRoute connPerRoute = new ConnPerRouteBean(12);
    ConnManagerParams.setMaxConnectionsPerRoute(params, connPerRoute);
    ConnManagerParams.setMaxTotalConnections(params, 20);

    // Set timeout
    HttpConnectionParams.setStaleCheckingEnabled(params, false);
    HttpConnectionParams.setConnectionTimeout(params, connectionTimeoutMillis);
    HttpConnectionParams.setSoTimeout(params, socketTimeoutMillis);
    HttpConnectionParams.setSocketBufferSize(params, 8192);

    // Some client params
    HttpClientParams.setRedirecting(params, false);
Http客户端创建

// load truststore certificate
            InputStream clientTruststoreIs = context.getResources().openRawResource(R.raw.server);
            KeyStore trustStore = KeyStore.getInstance("BKS");
            trustStore.load(clientTruststoreIs, "server".toCharArray());

            // initialize trust manager factory with the read truststore
            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init(trustStore);

            // setup client certificate

            // load client certificate
            InputStream keyStoreStream = context.getResources().openRawResource(R.raw.client);
            KeyStore keyStore = KeyStore.getInstance("BKS");
            keyStore.load(keyStoreStream, "client".toCharArray());

            // initialize key manager factory with the read client
            // certificate
            KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            keyManagerFactory.init(keyStore, "client".toCharArray());

            // initialize SSLSocketFactory to use the certificates
            SSLSocketFactory socketFactory = new SSLSocketFactory(SSLSocketFactory.TLS, keyStore, "client", trustStore, null, null);

            // Register http/s shemas!
            SchemeRegistry schReg = new SchemeRegistry();
            schReg.register(new Scheme("https", socketFactory, port));
            ClientConnectionManager conMgr = new ThreadSafeClientConnManager(params, schReg);

            httpClient = new DefaultHttpClient(conMgr, params);
客户端请求执行

HttpResponse response = httpClient.execute(request);
        HttpEntity entity = response.getEntity();
        in = entity.getContent();
        String result = convertStreamToString(in);
        in.close();

您正在使用线程安全连接管理器吗?如果不是,那么如果您在多个线程中使用同一个HttpClient,这可能就是问题所在


这篇文章有一些细节:

我对Android和HttpClient有着完全相同的问题——它似乎只有在使用客户端证书时才会表现出来,就像您所做的那样。删除客户端身份验证,它可以正常工作,但尚未找到解决方法

编辑:

启用陈旧连接检查

HttpConnectionParams.SetStaleCheckEnabled(参数,真)


帮我修好了。

谢谢你的回答。是的,正如你在我提供的代码中看到的那样。如果我在不使用SSL的情况下使用它,即使是从不同的线程使用,代码也可以很好地工作。但当我更改为SSL时,它会中断,顶部出现异常。还有其他建议吗?谢谢。只能在启用客户端证书的情况下确认这一点,这也为我解决了这一问题。