Socket流處理讀寫阻塞問題

 
從Socket上讀取對端發過來的數據通常有兩種方法:
1)按照字節流讀取
        BufferedInputStream in = new BufferedInputStream(socket.getInputStream());
        int r = -1;
        List<Byte> l = new LinkedList<Byte>();
        while ((r = in.read()) != -1) {
            l.add(Byte.valueOf((byte) r));
        }

2)按照字符流讀取
        BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));        
        String s;
        while ((s = in.readLine()) != null) {
            System.out.println("Reveived: " + s);
        }

這兩個方法read()和readLine()都會讀取對端發送過來的數據,若是無數據可讀,就會阻塞直到有數據可讀。或者到達流的末尾,這個時候分別返回-1和null。
這個特性使得編程很是方便也很高效。
可是這樣也有一個問題,就是如何讓程序從這兩個方法的阻塞調用中返回。

總結一下,有這麼幾個方法:
1)發送完後調用Socket的shutdownOutput()方法關閉輸出流,這樣對端的輸入流上的read操做就會返回-1。
注意不能調用socket.getInputStream().close()。這樣會致使socket被關閉。
固然若是不須要繼續在socket上進行讀操做,也能夠直接關閉socket。
可是這個方法不能用於通訊雙方須要屢次交互的狀況。

2)發送數據時,約定數據的首部固定字節數爲數據長度。這樣讀取到這個長度的數據後,就不繼續調用read方法。
3)爲了防止read操做形成程序永久掛起,還能夠給socket設置超時。 若是read()方法在設置時間內沒有讀取到數據,就會拋出一個java.net.SocketTimeoutException異常。 例以下面的方法設定超時3秒。 socket.setSoTimeout(3000);
相關文章
相關標籤/搜索