zoukankan      html  css  js  c++  java
  • Connection reset :readline 引起的socket读取异常

    在和银联进行联机交易时,突然出现无法读取响应的情况;

    报错信息如下:

    java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(SocketInputStream.java:196)
    at java.net.SocketInputStream.read(SocketInputStream.java:122)
    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:283)
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:325)
    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:177)
    at java.io.InputStreamReader.read(InputStreamReader.java:184)
    at java.io.BufferedReader.fill(BufferedReader.java:154)
    at java.io.BufferedReader.readLine(BufferedReader.java:317)
    at java.io.BufferedReader.readLine(BufferedReader.java:382)

    Connection reset是服务器关闭了连接,一直认为是服务器错误导致的;

    后来发现是代码中使用了 socket的readline方法导致的;

    原代码如下:

      socket = new Socket(this.serverHost, this.serverPort);
      socket.setSoTimeout(timeOut);
      writer = new PrintWriter(socket.getOutputStream());
      log.info("准备发送服务端数据: " + msg);
      writer.println(msg);
      writer.flush();
      log.info("请求完成, 准备接收返回");
      reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), Encoding.GBK));
      String resp = reader.readline();
      ......

    readline()方法会读到流结束或者 的时候返回。

    读取文件时,文件结尾就代表流结束,但是socket没有关闭的话就不会结束这个流。服务器在消息的结尾如果没有发送换行符 的话,也不会读取结束;

    解决方案:每次读取的报文大小由报文头决定

      socket = new Socket(this.serverHost, this.serverPort);
      socket.setSoTimeout(timeOut);
      writer = new PrintWriter(socket.getOutputStream());
      log.info("准备发送服务端数据: " + msg);
      writer.println(msg);
      writer.flush();
      log.info("请求完成, 准备接收返回");
      reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), Encoding.GBK));
      char[] rDataLen = new char[4];
      reader.read(rDataLen, 0, 4);
      int lenth = Integer.parseInt(new String(rDataLen));
      char[] rContentTxt = new char[lenth];
      reader.read(rContentTxt, 0, lenth);
      String response = new String(rDataLen) + new String(rContentTxt);

    至此,解决了这个问题;

  • 相关阅读:
    原来发布到主页是发布到博客园的主页啊,还真不知道
    sysobjects
    blend3破解文件,直接覆盖安装目录源文件即可。
    Microsoft Sql中char和varchar的区别与联系
    SQL脚本创建数据表,并给出主键,外键,唯一键,约束
    asp.net调试方法
    VS2010安装项目的系统必备中添加.NET 2.0
    c#,自定义安装,部署,创建自定义操作,自定义操作,安装验证,数据库,安装授权码,接收输入,判断
    Ext2.2系列(50篇)
    C# 获取24小时制的当前系统时间
  • 原文地址:https://www.cnblogs.com/chenhao0302/p/8418323.html
Copyright © 2011-2022 走看看