Java流的读取

来源:互联网 发布:学生女装品牌 知乎 编辑:程序博客网 时间:2024/05/22 14:49

         最近,写的报文j接收过程。错误代码如下:

byte[] mesLength=new byte[2];while((i=in.read(mesLength)) != -1) {if(i<2) break;int length=conv.byteToInt(mesLength);byte[] mes=new byte[length];int j=in.read(mes);if(j!=length) break;        ......}

 我的本意是,先从流里读出2个字节的长度,而后读出该长度的报文内容。

而此处,我的判断条件i<2,本意是如果流里只有一个字节,则停止接收,还有下面,“int j=in.read(mes)”本意也是如果流结束前,没有读到指定长度,则停止接收。没有异常的情况下,或许你觉得这样理所当然。但是这正是对java流的一种错误理解。

        “in.read()"会从输入流读取信息,但是一次read可能由于异常等,并不能得到我们需求的字节数,因而正确的读法是:

int bytesRead = 0;            //已读到字节数int bytesToread =1024;        //需求字节数byte[] input = new byte[bytesToRead];while ( bytesRead < bytesToRead ){bytesRead + = in.read(input, bytesRead,bytesToRead-bytesRead);}

按照上面的读法,我们才能读到需求的字节数。通过一次读取,可能由于某些原因并不能得到需求长度的字节数。这是我以上代码的一个错误。而另一个错误,则是判断流里数据的长度时无意义的。因为在下一次循环之前,我们都不能确定,流是否读完,下一次也不能确定。我们的流,就是简单的用来接收数据的,我们不该把对报文长度的校验放到此处,那么我们该如何处理呢,我们可以设置超时,这样,当一直读取不到需求长度的字节时,我们就可以关闭本次连接了。这样,即使我们是多线程处理,也可以保证受到上述错误格式攻击时,不会由于开启大量线程,而耗尽资源。

        当然,这也与我初始定义的应答码有关,应答码中有个格式错误,经过上述考虑,格式错误可以取消。

        上文仅供抛砖引玉,望多多指教。