使用SSLSocket传输inputStream.available(0) = 0

记录一下项目中SSLSocket的坑

  private void readStreamOld(byte[] out) throws IOException
   {
     byte[] reading = null;
     ByteArrayOutputStream cache = new ByteArrayOutputStream();
     int total = out.length;
    while (total > 0) {
      int amount = total;
      int available = in.available();
	     if (amount > available) {
	        amount = available;
	      }
         reading = new byte[amount];
        in.read(reading);
        cache.write(reading);
        total -= amount;
      }
    new java.io.ByteArrayInputStream(cache.toByteArray()).read(out);
   }

上面这段代码是服务端读取输入流的代码,当使用socket通信时,不会出错。

但是当使用sslsocket通信时,就会阻塞,最终导致客户端产生以下错误:

 经过debug发现当使用sslsocket通信时,当握手成功之后, client向server端先发送第一段信息后,in.available() = 0,导致server逻辑死循环导致阻塞。

网上查询资料翻译可知:

InputSteam的available()方法的功能是返回该输入流可以在不阻塞的情况下读取的字节数。网络流和文件流之间区别的关键在于它是否被“阻止”。读取网络套接字流时,如果没有内容,read()方法将被阻止,因此从套接字初始化的可用输入流也为零。因此,在使用前必须先读取一个字节,以便可用字节数等于可用字节数+1。但是读取文件时,read()通常不会被阻止,因为文件流的可用字节数为available=file。length(),创建文件对象时,文件的内容长度是已知的。因此,在调用网络流(socket)的available()方法之前,必须记住首先调用read()方法,以避免获取0的错误情况。

//Store the received data in the byte array bytes
    int firstByte = inputStream.read();
    int length = inputStream.available();
    byte[] bytes = new byte[length+1];
    bytes[0] = (byte)firstByte;
    inputStream.read(bytes,1,length);

上述报错方法改为

 private void readStream(byte[] out) throws IOException
   {
     byte[] reading = null;
    ByteArrayOutputStream cache = new ByteArrayOutputStream();
    int total = out.length;
     while (total > 0) {
      int amount = total;
      int firstbyte = in.read();
      int available = in.available();
      if (amount > available+1) {
        amount = available+1;
       }
       reading = new byte[amount];
       reading[0] = (byte)firstbyte;
       in.read(reading,1,amount-1);
       cache.write(reading);
      total -= amount;
     }
     new java.io.ByteArrayInputStream(cache.toByteArray()).read(out);
   }

 问题就解决了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值