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()方法会读到流结束或者\n的时候返回。

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

 

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

 

  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);

至此,解决了这个问题;

 

转载于:https://www.cnblogs.com/chenhao0302/p/8418323.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值