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();
相关推荐
2601_9638699520 小时前
【计算机毕业设计】基于 Spring Boot+Vue的手工体验馆管理系统的设计与实现
java·spring boot·后端
曹牧21 小时前
Java:BeanListHandler
java·数据库·oracle
江畔柳前堤1 天前
roLabelImg 详细安装教程
开发语言·人工智能·后端·云原生
Wang's Blog1 天前
Go-Zero 项目开发47:自研微服务框架的必要性与核心结构设计
开发语言·微服务·golang
白鸽(二般)1 天前
MinIO Java Client API
java·开发语言
hPw0eKIqD1 天前
C++ 模板参数推导问题小记(非推导上下文)
开发语言·c++
临床数据科学和人工智能兴趣组1 天前
要使用 R Markdown,首先需要安装 R 和 RStudio,接着安装 rmarkdown 包
开发语言·数据挖掘·数据分析·r语言·r语言-4.2.1
软萌萌的11 天前
Java Spring Boot 修改yml配置&加载顺序规则
java·spring boot·python
Nebula嵌入式1 天前
【C语言】09-深入解析main函数
linux·c语言·开发语言·嵌入式
IT小盘1 天前
13-企业Prompt模板-角色任务约束与输出格式
java·前端·prompt