1.TCP中的in.read()读到-1仅表示当前缓冲区里无数据,并非之后一直会无数据,等待一段时间之后可能会再有数据。
available()也一样没有效果,如果available()的返回值为0只表示当前缓冲区中无数据,也不能作为读完数据的标志。
判断数据包的结尾要使用特殊的结束符,或等到数据读取时超时,因此CMPP、SGIP协议时均采用发送链路保持包,有些协议采用心跳包,一方面是检测通信两端是否都正常,另一方面是为了防止出现超时链接断开的情况。
2.in.read(byte[])、in.read(byte b[],int off, int len)均是调用in.read(),因此使用in.read()效率一样。
3.在HTTP中读取服务端的数据时,判断是否已经结尾,是要先看包头,如果包头中有包体的长度(即指定了Content-Length)则读到该长度后即可算作结束,可断开连接。
如果未指定包体长度,则应该是用了chunked方式:Transfer-Encoding: chunked,即包体分块,每块的开头处为长度,则要一段段的读取。对于无包体的情况,也会在包体中加入一个\r\n0\r\n
因此读取HTTP返回包时,必须先读取HTTP的包头,再根据包头的值来确定如何读,以及读多少数据,千万不能根据读到-1或available()为0来判断读到结尾。
判断读到HTTP包头的结尾是要找到\r\n\r\n。
4.如果定义了InputStream流in,再以该in为参数创建BufferedReader流reader,则使用reader读数据时,再用in来读则不会从reader当前读到的位置继续读,可能未读到的字节数会减少。因此应该一直用reader读,或者用in读。
5.如果HTTP返回包的格式为chunked+gzip,则每块chunked块头部指定的长度与实际长度一致,非chunked编码之前的长度
如果有多块chunked,可以先把每块的字节数组合并合并,之后一块解压?
6.在读输入流时,如果读到一部分还未读完就进行调试,有可能会丢掉一些输入的字节,如果连续的读则不会丢失,时间过长还会使得输入流失效。
本文地址:http://www.caihonger.com/tech9/