关于InputStream.read()方法的阻塞原理的测试

  最近在一家公司作java实习,写了个网络字节采集器。写了个单例TCPServer来采集数据,其中用到了InputStream.read()来读取数据。产生了一系列问题,下面作下总结:java

  关于while((length = is.read(data)) != -1)问题。网络

  在写此方法时,产生了一些疑惑,read什么时候阻塞?什么时候返回值-1?socket

  

  首先作个假设:测试

  一、读不满data的length就一直阻塞。为此,作了如下实验:spa

  Server端:get

      byte[] data = new byte[8];it

while((length = is.read(data)) != -1){
  String result = new String(data);
  System.out.println(result);
  System.out.println("length:" + length);
}循环

客户端:程序

String msg = "ab";方法

byte[] byteMsg = msg.getBytes();

Socket socket = new Socket("127.0.0.1", 9999);
OutputStream out = socket.getOutputStream();
BufferedOutputStream bw = new BufferedOutputStream(out);
for (int i = 0;i<10;i++) {
  bw.write(byteMsg);

  bw.flush();

}

发现服务端在length=2时,就输出了,结果为ab。说明并非在data读不满时就一直阻塞。

二、那么是否是跟flush()有关呢?

下面将bw.flush()注视,发现,并追加代码Thread.sleep(5*1000),让它每次输出2个字节后暂停5秒,以达到网络不好的目的。发现服务端每次输出abababab 8个长度的字节。则能够断定跟flush有关。

三、那何时缓冲区的数据会flush呢?

和另外一网络组的程序对接读数据,他每次都发送148个字节长度的数据,并循环一直发,而我这边依次解析148长度的数据。但发现时间久了数据就会对不拢。分析错误数据发现是没有读完148,而下次再读时将剩余没读完的部分加在了本次的头部,当然出错。因而有个疑问:我这边每次都是读148个字节,而后处理,为何会有读不满148的状况?根据前两个的测试,初步判断跟flush有关。多是网络层数据缓冲区在数据量超过必定范围时自动flush了。测试以下:

客户端:

String msg = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
byte[] byteMsg = msg.getBytes();

try {

Socket socket = new Socket("127.0.0.1", 9999);
OutputStream out = socket.getOutputStream();
BufferedOutputStream bw = new BufferedOutputStream(out);
for (;;) {
bw.write(byteMsg);

//这里不进行程序flush,一直发。

  }

  服务端:

int count = 1000000;
is = socket.getInputStream();
byte[] data = new byte[count];
int length = 0;
while((length = is.read(data)) != -1){
  String result = new String(data);
  System.out.println(result);
  System.out.println("length:" + length);
}

发现输出以下:

aaaaaaa..............行太长

length:39960

  aaaaaaa..............行太长

  length:23976

  aaaaaaa..............行太长

  length:23976

  aaaaaaa..............行太长

  length:24745

  aaaaaaa..............行太长

  length:25435

  aaaaaaa..............行太长

  length:21748

  说明网络层缓冲区在长度必定时,就自动flush,可是这个长度好像不是很固定。长度取决于什么如今还不清楚。

相关文章
相关标签/搜索