java.net.SocketException: Connection reset 異常原因分析和解決方法


Connection reset : 一般是客戶端正在從服務器讀數據時或者向服務器寫數據時,服務器連接關閉,通過tcpdump抓包可以看到,返回了一個RST復位標志,導致連接重置。

導致此異常的原因,總結下來有三種情況:

1.服務器端偶爾出現了異常,導致連接關閉

解決方法: 采用出錯重試機制

2.服務器端和客戶端使用的連接方式不一致

解決方法:服務器端和客戶端使用相同的連接方式,即同時使用長連接或短連接

3.如果是HTTPS,那么還存在TLS版本不一致

解決方法:服務器端和客戶端使用相同的TLS版本

附錄:JDK中對 HTTPS 版本的支持情況:
JDK 6
    SSL v3
    TLS v1(默認)
    TLS v1.1(JDK6 update 111 及以上)
JDK 7
    SSLv3
    TLS v1(默認)
    TLS v1.1
    TLS v1.2
JDK 8
    SSL v3
    TLS v1
    TLS v1.1
    TLS v1.2(默認)

方法一:如果客戶端JDK是1.7,服務器端要求TLSv1.2,那么在啟動參數加上-Dhttps.protocols=TLSv1.2即可。

方法二:代碼指定TLS版本 System.setProperty("https.protocols", "TLSv1.2");

方法三:可以用以下工具類方法解決:

public class HttpClientFactory {
    private static CloseableHttpClient client;

    public static HttpClient getHttpsClient() throws Exception {

        if (client != null) {
            return client;
        }
        SSLContext sslcontext = SSLContexts.custom().useSSL().build();
        sslcontext.init(null, new X509TrustManager[]{new HttpsTrustManager()}, new SecureRandom());
        SSLConnectionSocketFactory factory = new SSLConnectionSocketFactory(sslcontext,new String[] { "SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2" }, null,
                SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
        client = HttpClients.custom().setSSLSocketFactory(factory).build();

        return client;
    }

    public static void releaseInstance() {
        client = null;
    }
}
public class HttpsTrustManager implements X509TrustManager {

    @Override
    public void checkClientTrusted(X509Certificate[] arg0, String arg1)
            throws CertificateException {
        // TODO Auto-generated method stub

    }

    @Override
    public void checkServerTrusted(X509Certificate[] arg0, String arg1)
            throws CertificateException {
        // TODO Auto-generated method stub

    }

    @Override
    public X509Certificate[] getAcceptedIssuers() {
        return new X509Certificate[]{};
    }

}

調用方式如下:

    HttpClient httpClient = HttpClientFactory.getHttpsClient();
    HttpPost request = new HttpPost(requestUrl);
    request.setEntity(new StringEntity(gson.toJson(requestMap), "application/json", "UTF-8"));

    HttpResponse httpResponse = httpClient.execute(request);
    resultStr = EntityUtils.toString(httpResponse.getEntity(), "UTF-8");
    System.out.println(resultStr);
    httpResponse.getEntity().getContent().close();

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2024 CODEPRJ.COM