Socket java.net.SocketException: Connection reset的解决方案[通俗易懂]

Socket java.net.SocketException: Connection reset的解决方案[通俗易懂]背景:服务端通讯方式:TCP/IPsocket短链接。首先看下我的最开始的socket代码:publicstaticbyte[]sendMessage(Stringurl,intport,byte[]request,inttimeout){byte[]res=null;Socketsocket=n

大家好,又见面了,我是你们的朋友全栈君。

背景:
服务端通讯方式:TCP/IP socket 短链接。
首先看下我的最开始的socket代码:

public static byte[] sendMessage(String url, int port, byte[] request, int timeout) {
        byte[] res = null;
        Socket socket = null;
        InputStream is = null;
        OutputStream os = null;
        try {
            socket = new Socket(url, port);
            socket.setSoTimeout(timeout);
            is = socket.getInputStream();
            os = socket.getOutputStream();
            os.write(request);
            os.flush();
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            byte[] buffer = new byte[8192];
            int count;
            while ((count = is.read(buffer)) != -1) {
                bos.write(buffer, 0, count);
            }
            res = bos.toByteArray();
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            try {
                if (os != null) {
                    os.close();
                }
                if (is != null) {
                    is.close();
                }
                if (socket != null) {
                    socket.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
        return res;
    }

上面这段代码,是最常用的的socket 发送方式,对于一般的socket链接都适用。但是在这里跟银行联调时一直报了一个错:
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:196)
at java.net.SocketInputStream.read(SocketInputStream.java:122)
at java.net.SocketInputStream.read(SocketInputStream.java:108)
经查阅问题描述如下:
1,如果一端的Socket被关闭(或主动关闭,或因为异常退出而 引起的关闭),另一端仍发送数据,发送的第一个数据包引发该异常(Connect reset by peer)。

2,一端退出,但退出时并未关闭该连接,另一端如果在从连接中读数据则抛出该异常(Connection reset)。简单的说就是在连接断开后的读和写操作引起的。

我这里是客户端,socket最后关闭,原因只能是2。说明对方在把数据返回后,就把socket关闭了,而客户端还在读数据。所以就connection reset。

解决方案;
使用InputStream.available判定是否还有可读字节
available()
返回下一次对此输入流调用的方法可以不受阻塞地从此输入流读取(或跳过)的估计剩余字节数。
如下:

 public static byte[] sendMessage(String url, int port, byte[] request) {
        byte[] res = null;
        Socket socket = null;
        InputStream is = null;
        OutputStream os = null;
        try {
            socket = new Socket(url, port);
            os = socket.getOutputStream();
            os.write(request);
            os.flush();
            is = socket.getInputStream();
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int count = 0;
            do {
                count = is.read(buffer);
                bos.write(buffer, 0, count);
            } while (is.available() != 0);
            res = bos.toByteArray();
            os.close();
            is.close();
            socket.close();
        } catch (Exception ex) {
            try {
                if (is != null) {
                    is.close();
                }
                if (socket != null)
                    socket.close();
            } catch (Exception e) {
            }
        }
        return res;
    }
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/158570.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • pycharm2021年激活码刚出【2021.7最新】

    (pycharm2021年激活码刚出)最近有小伙伴私信我,问我这边有没有免费的intellijIdea的激活码,然后我将全栈君台教程分享给他了。激活成功之后他一直表示感谢,哈哈~https://javaforall.net/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~TR0L…

    2022年3月22日
    53
  • mysql中去重 distinct 用法「建议收藏」

    mysql中去重 distinct 用法

    2022年2月10日
    367
  • pycharm激活码 2021(注册激活)

    (pycharm激活码 2021)好多小伙伴总是说激活码老是失效,太麻烦,关注/收藏全栈君太难教程,2021永久激活的方法等着你。IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.html1435QFILVV-eyJsaWNlbnNlSWQi…

    2022年3月30日
    359
  • go语言微服务之RPC协议[通俗易懂]

    go语言微服务之RPC协议[通俗易懂]1什么是RPCRemoteProcedureCallProtocol–远程过程调用协议!IPC:进程间通信RPC:远程进程通信–应用层协议(http协议同层),底层用TCP实现。理解RPC:像调用本地函数一样,去调用远程函数。通过rpc协议,传递:函数名,函数参数。达到在本地,调用远端函数,得返回值到本地的目标。 为什么微服务要使用RPC:每个服务都被封转成进程,彼此“独立”。 进程与进程之间,可以使用不同的语言实现。2RPC使用的步骤服务端:注册rpc

    2022年5月12日
    53
  • C#操作xml文件:使用XmlDocument 实现读取和写入

    C#操作xml文件:使用XmlDocument 实现读取和写入XML文件是一种常用的文件格式,例如WinForm里面的app.config以及Web程序中的web.config文件,还有许多重要的场所都有它的身影。Xml是Internet环境中跨平台的,依赖于内容的技术,是当前处理结构化文档信息的有力工具。XML是一种简单的数据存储语言,使用一系列简单的标记描述数据,而这些标记可以用方便的方式建立,虽然XML占用的空间比二进制数据要占用更多的空间,但XML极…

    2022年6月22日
    22
  • OpenResty 最佳实践学习–实战演习笔记(2)

    在前面一篇中已经介绍了Openresty的相关知识和一个简单的hello world的访问。本篇依然是延续上一篇进行讲解。 需要提前申明的是我环境有问题。重新安装了一次openresty,这次安装的目录和上一次不一样了。一:环境说明:虚拟机 :CentOs 6.3 32位OpenResty 安装目录 : /opt/openresty/版本: /opt/openresty/nginx/sbi

    2022年2月26日
    51

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号