筆者在編寫基於BIO實現服務器復讀客戶端信息的小實驗時,使用了read方法來遍歷讀取inputStream中的內容,諸如FileInputstream中,當流讀取完畢時,read便會返回-1以表示讀取完畢,筆者想固然的也使用該邏輯來判斷流讀取完畢。代碼運行以後,客戶端發送到服務端的數據以後,遲遲未收到返回的數據,經排查是堵塞在了讀取流的地方。通過查閱資料,socketInputStream的read方法,在沒有數據讀取時,並不會返回-1,而是會一直堵塞,等待新數據的傳輸。java
那麼什麼時候關閉流呢?在網絡編程中,流什麼時候進行關閉,有如下幾種方法。編程
1)發送完後調用Socket的shutdownOutput()方法關閉輸出流,這樣對端的輸入流上的read操做就會返回-1。
注意不能調用socket.getInputStream().close()。這樣會致使socket被關閉。
固然若是不須要繼續在socket上進行讀操做,也能夠直接關閉socket。
可是這個方法不能用於通訊雙方須要屢次交互的狀況。服務器
2)發送數據時,約定數據的首部固定字節數爲數據長度。這樣讀取到這個長度的數據後,就不繼續調用read方法。網絡
3)爲了防止read操做形成程序永久掛起,還能夠給socket設置超時。
若是read()方法在設置時間內沒有讀取到數據,就會拋出一個java.net.SocketTimeoutException異常。
例以下面的方法設定超時3秒。
socket.setSoTimeout(3000);
socket