byte数组转short,从byte数组中获取前两位代表的整个byte字节长度的字节

在做socket请求对方接口的时候遇到了以下问题

1、第一次使用固定的字节长度4096来读取对方返回的数据时遇到了没读完的情况,这时候怀疑设置的长度问题

			sClient = new Socket(ip, 端口);
            sClient.setSoTimeout(超时时间);
            byte[] sendBytes = BasicUtil.str2bcd(reqXml);
            sClient.getOutputStream().write(sendBytes, 0, sendBytes.length);
            sClient.getOutputStream().flush();
            byte[] dataLen = new byte[4096];
            sClient.getInputStream().read(dataLen);
            String result = new String(dataLen); //读取的数据不完整

2、这时候换成了下面使用循环来读的方法,这时候又出现了另外的问题,发现数据循环已经读完了还一直没结束,直到一分钟才返回,这时候想到自己设置的超时时间是1分钟,觉得有它的原因,但是超时时间是如果读完立马返回是没有影响的啊。后面才想到对方使用的是长连接的方式,因为对方一直不关闭我这边就认为没读完,就会一直读完还会继续等待,直到超时时间结束。

			sClient = new Socket(ip, 端口);
            sClient.setSoTimeout(超时时间);
            byte[] sendBytes = BasicUtil.str2bcd(reqXml);
            OutputStream os = sClient.getOutputStream();
            os.write(sendBytes, 0, sendBytes.length);
            os.flush();
            InputStream inputStream = sClient.getInputStream();
            byte[] dataLen = new byte[1024];
            int len2;
            while((len2 = inputStream.read(dataLen)) != -1) {
    
    
                result.append(new String(dataLen,0,len2, StandardCharsets.UTF_8));
                logger.info("原始返回报文" + result);
            }

3、第三次优化,因为这时候还没对方的文档,不知道是采用什么协议,所以这次就每次读64字节,然后设置超时时间为1秒,这次能读完了,但是后台却会报读取超时的异常,虽然没什么影响,想到这,原因还是因为长连接的问题,因为最后一次发起请求到超时时间结束还没拿到结果。

sClient = new Socket(ip, 端口);
            sClient.setSoTimeout(1);
            byte[] sendBytes = BasicUtil.str2bcd(reqXml);
            OutputStream os = sClient.getOutputStream();
            os.write(sendBytes, 0, sendBytes.length);
            os.flush();
            InputStream inputStream = sClient.getInputStream();
            byte[] dataLen = new byte[64];
            int len2;
            while((len2 = inputStream.read(dataLen)) != -1) {
    
    
                result.append(new String(dataLen,0,len2, StandardCharsets.UTF_8));
                logger.info("原始返回报文" + result);
            }

4、拿到文档后才知道对方返回的报文中前2个字节代表的是此次报文的总长度
在这里插入图片描述
5、这时候就知道了,要先读取获取到整个报文的长度字节,最后再尝试多次后

sClient = new Socket(serverIp, Integer.parseInt(port));
            sClient.setSoTimeout(Integer.parseInt(timeOut));
            byte[] sendBytes = BasicUtil.str2bcd(reqXml);
            sClient.getOutputStream().write(sendBytes, 0, sendBytes.length);
            sClient.getOutputStream().flush();
            byte[] dataLen = new byte[2];
            sClient.getInputStream().read(dataLen);
            short buffer =  ByteBuffer.wrap(dataLen).order(ByteOrder.BIG_ENDIAN).getShort();;
            logger.info("----------->length: " + buffer);
            dataLen=new byte[buffer];
            sClient.getInputStream().read(dataLen);
            String result = new String(dataLen,"GBK"); //new String(arr);

先读取2字节,前2个字节代表报文长度,拿到长度再度一次剩下的字节

猜你喜欢

转载自blog.csdn.net/weixin_42857718/article/details/129750230