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);


免責聲明!

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



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