關於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,可是這個長度好像不是很固定。長度取決於什麼如今還不清楚。

相關文章
相關標籤/搜索