美文网首页
异常记录——Connection reset

异常记录——Connection reset

作者: 橙味菌 | 来源:发表于2020-01-03 17:13 被阅读0次

    连接重置Connection reset

    异常java.net.SocketException: Connection reset

    详细信息

    java.net.SocketException: Connection reset
        at java.net.SocketInputStream.read(SocketInputStream.java:210)
        at java.net.SocketInputStream.read(SocketInputStream.java:141)
        at sun.security.ssl.InputRecord.readFully(InputRecord.java:465)
        at sun.security.ssl.InputRecord.read(InputRecord.java:503)
        at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:975)
        at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1367)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1395)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1379)
        at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:396)
        at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:355)
        at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:142)
        at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:373)
        at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:381)
        at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:237)
        at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:185)
        at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
        at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:111)
        at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
        at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
        at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108)
        at com.senthink.www.oc.http.HttpRequester.execute(HttpRequester.java:170)
    

    场景回溯

    1. 首次请求 首次向电信物联网平台API发送Https请求时报错
    2. 未得到响应
    3. 只有Soctet异常:Connection Reset

    出现原因

    Connection Reset——其中一端主动断开连接

    Connection Reset是在建立TCP连接之后,其中一方的TCP标志位使用了Reset标志主动重置了连接

    客户端Or服务器端

    而我这里既然是客户端报的错误信息,那势必是服务器主动断开了连接

    为什么它要断开连接

    服务器主动断开连接的原因:

    • 服务器异常

    • 服务器和客户端长短连接不匹配

    • Https连接,服务器和客户端的TLS版本不一致

    原因排查

    • 服务器异常 电信作为三大运营商,它的服务器出现异常的可能性不大
    • 长短连接不匹配 如果是长短连接不匹配,那么也是第一次响应之后短连接方断开连接,而我跟本没有收到响应,因此可以排除长短连接不一致的情况
    • Https连接,TLS版本不一致

    用排除法分析出:此时连接重置的原因是TLS版本不一致

    解决方法

    • 试出来服务器端支持的TLS版本

      1. 打开Http客户端的配置(我用的是HttpClient,它的TLS配置在SSL连接工厂中的String数组参数)

        public CloseableHttpClient closeableHttpClient() throws Exception {
            // Trust own CA and all self-signed certs
            String userDir = System.getProperty("user.dir");
            SSLContext sslcontext = SSLContexts.custom()
                .loadTrustMaterial(
                new File(userDir + ocSetting.getCertPathCA()),
                ocSetting.getCertPasswordCA().toCharArray(),
                new TrustSelfSignedStrategy())
                .loadKeyMaterial(
                new File(userDir + ocSetting.getCertPathOutGoing()),
                ocSetting.getCertPasswordOutGoing().toCharArray(),
                ocSetting.getCertPasswordOutGoing().toCharArray())
                .build();
            // Allow TLSv1 protocol only
            //这里的问题,这里配置只允许TLSv1版本
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                sslcontext,
                new String[] { "TLSv1"},
                //new String[] {"TLSv1","TLSv1.1","TLSv1.2",疯狂往里加}
                null,
                SSLConnectionSocketFactory.getDefaultHostnameVerifier());
        
            return HttpClients.custom().setSSLSocketFactory(sslsf).build();
        }
        
      2. 以此切换TLS版本,直到不再出现Connection Reset

        TLS版本有哪些?,这个在sun.security.ssl.ProtocolVersion中可以看到

        static final ProtocolVersion NONE = new ProtocolVersion(-1, "NONE");
        static final ProtocolVersion SSL20Hello = new ProtocolVersion(2, "SSLv2Hello");
        static final ProtocolVersion SSL30 = new ProtocolVersion(768, "SSLv3");
        static final ProtocolVersion TLS10 = new ProtocolVersion(769, "TLSv1");
        static final ProtocolVersion TLS11 = new ProtocolVersion(770, "TLSv1.1");
        static final ProtocolVersion TLS12 = new ProtocolVersion(771, "TLSv1.2");
        
      3. 换上服务器支持的TLS版本,问题解决

    技术不分领域,思想一脉相承,欢迎访问橙味菌的博客
    本文由博客一文多发平台 OpenWrite 发布!

    相关文章

      网友评论

          本文标题:异常记录——Connection reset

          本文链接:https://www.haomeiwen.com/subject/stftactx.html