javax.net.ssl.SSLException : Read error: ssl=0x56e63588: I/O error during system call, 连接被对等重置

标签 java android ssl sslexception

在过去的 2 年里,我一直使用 org.apache.http.client.HttpClient 从 HTTP 服务器下载一些数据,并且运行良好。

最近我们出于某些安全原因切换到 HTTPS。这也适用于 WiFi 和高速移动数据 (3G)。但最常见的是低速数据连接 (2G) 我的下载因以下堆栈跟踪而中断。

 javax.net.ssl.SSLException: Read error: ssl=0x56e63588: I/O error during system call, Connection reset by peer
    at com.android.org.conscrypt.NativeCrypto.SSL_read(Native Method)
    at com.android.org.conscrypt.OpenSSLSocketImpl$SSLInputStream.read(OpenSSLSocketImpl.java:690)
    at org.apache.http.impl.io.AbstractSessionInputBuffer.fillBuffer(AbstractSessionInputBuffer.java:103)
    at org.apache.http.impl.io.AbstractSessionInputBuffer.read(AbstractSessionInputBuffer.java:120)
    at org.apache.http.impl.io.ChunkedInputStream.read(ChunkedInputStream.java:131)
    at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:140)
    at java.io.FilterInputStream.read(FilterInputStream.java:114)

这就是我的代码的样子:

                HttpPost httpPost = new HttpPost(url);
                UrlEncodedFormEntity p_entity = new UrlEncodedFormEntity(
                        params, HTTP.UTF_8);
                httpPost.setEntity(p_entity);
                response = httpClient.execute(httpPost);
                DataInputStream in = new               DataInputStream(response.getEntity().getContent());
                String st = "";
                result = new Vector<String>();
                while ((st = readLine(in)) != null) {
                result.addElement(st);
         }

最佳答案

试试这个:

 package com.telpoo.frame.net;

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.http.HttpVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;

public class MySSLSocketFactory extends SSLSocketFactory {
    SSLContext sslContext = SSLContext.getInstance("TLS");

    public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
        super(truststore);

        TrustManager tm = new X509TrustManager() {
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }

            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }

            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        };

        sslContext.init(null, new TrustManager[] { tm }, null);
    }

    @Override
    public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
        return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
    }

    @Override
    public Socket createSocket() throws IOException {
        return sslContext.getSocketFactory().createSocket();
    }

    public static  HttpClient getNewHttpClient() {
        try {
            KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
            trustStore.load(null, null);

            SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
            sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

            HttpParams params = new BasicHttpParams();
            HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
            HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);

            SchemeRegistry registry = new SchemeRegistry();
            registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
            registry.register(new Scheme("https", sf, 443));

            ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);

            return new DefaultHttpClient(ccm, params);
        } catch (Exception e) {
            return new DefaultHttpClient();
        }
    }

}

并使用它:

URL myUrl = new URL(url);
            HttpClient client = MySSLSocketFactory.getNewHttpClient(); // myHttpClient();

            HttpConnectionParams.setConnectionTimeout(client.getParams(), connectTimeout);

    HttpPost post = new HttpPost(myUrl.toURI());

关于javax.net.ssl.SSLException : Read error: ssl=0x56e63588: I/O error during system call, 连接被对等重置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28233303/

相关文章:

java - 同步静态方法在 android 中不起作用?

java - Android ListView 填充内容而不移动 ListView 高度?

python - 尝试使用 websocket-client 建立 https 连接时出现 SSL 错误

android - 预览Camera with Kotlin实景应该选择哪个view?

caching - 从 JavaScript 清除 SSL 客户端证书状态

iphone - 我们如何告诉 CFStream 使用一组 anchor 证书?

Java程序计算我在另一个星球上的体重

java - 为什么gradle在:app:lint期间尝试下载Kotlin编译器?

java - 合并排序算法不对后半部分进行排序

android - 如何检查 Android SQLite 数据库中是否存在表?