Socket和InputStream阻塞的問題
阿新 • • 發佈:2019-01-23
因為要做一個和Socket有關的專案,今天發現InputStream的read()方法會在一直阻塞,即使客戶端的請求已經發送完畢,伺服器端也將客戶端請求完全讀完!程式碼如下:
- InputStream in = client.getInputStream();
- StringBuffer buf = new StringBuffer();
- int i = in.read();
- while(i!=-1){
- buf.append((char)i);
- i = in.read(); //阻塞
- }
但是用read(byte[] b)時只有在流位元組數是b長度的整數倍會阻塞,程式碼如下:
- InputStream in = client.getInputStream();
- byte[] bf = newbyte[1024];
- int result = in.read(bf);
- while(result != -1){
- result = in.read(bf); //只有當流裡的位元組數是1024的整數倍會阻塞
- }
後來分析了一下原因如下:
1.read()方法的API說如果因為已經到達流末尾而沒有可用的位元組,則返回值 -1
。在輸入資料可用、檢測到流末尾或者丟擲異常前,此方法一直阻塞。而Socket在未關閉之前是不會關閉流的。所以read()方法就不知道什麼時候到了流的末尾,就會一直阻塞。(如在檔案輸入之後shutdownOutput,read不會阻塞,但這樣會導致無法再次輸入 :...out.flush();socket.shutdownOutput();...)
2.read(byte[] b)當流裡的位元組數不為b的長度整數倍,在最後一次讀取時由於流裡所剩的位元組數小於b的長度,流就認為到了流的末尾。如果為整數的話阻塞原因同上。