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();
相关推荐
Chester_19997 小时前
CSP202203C.计算资源调度器
开发语言·数据结构·c++·蓝桥杯
EXI-小洲8 小时前
Java 操作 Word:字符串替换、图片插入、动态生成表格与API接口下载
java·开发语言·spring boot·word
会周易的程序员9 小时前
给 PLC 写一个字节码虚拟机:STVM 虚拟机架构设计
开发语言·c++·虚拟机·软plc·iec61131·stvm
机器视觉知识推荐、就业指导9 小时前
为什么老说“纯 Qt 没啥就业市场”?
开发语言·qt
telepan9 小时前
Qt 开发避坑与性能指南:如何优雅、安全地定义全局常量字符串?
开发语言·qt
m0_695251499 小时前
Qt MaintenanceTool 使用国内镜像加速下载(超详细教程)
开发语言·qt
2601_961901709 小时前
SpringBoot使用Nacos进行application.yml配置管理
java·spring boot·spring
何以解忧,唯有..10 小时前
LangChain 工具调用(Tool Calling)实战指南
java·前端·langchain
大衛說10 小时前
《Python 从入门到精通》系列总览与学习路线
开发语言·python·学习
QQ_216962909610 小时前
【源码编号:project79475】SpringBoot校内二手交易平台:商品发布、分类检索、留言交流、订单管理全流程实战
java·spring boot·后端