關於InputStream.read()方法的阻塞原理的測試


  最近在一家公司做java實習,寫了個網絡字節采集器。寫了個單例TCPServer來采集數據,其中用到了InputStream.read()來讀取數據。產生了一系列問題,下面做下總結:

  關於while((length = is.read(data)) != -1)問題。

  在寫此方法時,產生了一些疑惑,read何時阻塞?何時返回值-1?

  

  首先做個假設:

  1、讀不滿data的length就一直阻塞。為此,做了以下實驗:

  Server端:

      byte[] data = new byte[8];

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讀不滿時就一直阻塞。

2、那么是不是跟flush()有關呢?

下面將bw.flush()注視,發現,並追加代碼Thread.sleep(5*1000),讓它每次輸出2個字節后暫停5秒,以達到網絡很差的目的。發現服務端每次輸出abababab 8個長度的字節。則可以判定跟flush有關。

3、那什么時候緩沖區的數據會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,但是這個長度好像不是很固定。長度取決於什么現在還不清楚。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM