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

导致此异常的原因,总结下来有三种情况:

一、服务器端偶尔出现了异常,导致连接关闭
解决方法: 采用出错重试机制

二、 服务器端和客户端使用的连接方式不一致
解决方法: 服务器端和客户端使用相同的连接方式,即同时使用长连接或短连接

三、如果是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"); (我是通过这种方式,加了一行代码解决的)

方法三:可以用以下工具类方法解决:

javascript 复制代码
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;
    }
}
javascript 复制代码
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[]{};
    }

}

调用方式如下:

javascript 复制代码
  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();
相关推荐
皮皮林5512 小时前
Java性能调优黑科技!1行代码实现毫秒级耗时追踪,效率飙升300%!
java
冰_河2 小时前
QPS从300到3100:我靠一行代码让接口性能暴涨10倍,系统性能原地起飞!!
java·后端·性能优化
桦说编程5 小时前
从 ForkJoinPool 的 Compensate 看并发框架的线程补偿思想
java·后端·源码阅读
躺平大鹅7 小时前
Java面向对象入门(类与对象,新手秒懂)
java
初次攀爬者8 小时前
RocketMQ在Spring Boot上的基础使用
java·spring boot·rocketmq
花花无缺8 小时前
搞懂@Autowired 与@Resuorce
java·spring boot·后端
Derek_Smart9 小时前
从一次 OOM 事故说起:打造生产级的 JVM 健康检查组件
java·jvm·spring boot
NE_STOP10 小时前
MyBatis-mybatis入门与增删改查
java
孟陬13 小时前
国外技术周刊 #1:Paul Graham 重新分享最受欢迎的文章《创作者的品味》、本周被划线最多 YouTube《如何在 19 分钟内学会 AI》、为何我不
java·前端·后端