2017-07-20 142 views
1

首先請原諒我,如果我誤認爲阻塞是如何工作的,我的理解阻塞會暫停線程直到它準備好,例如當讀取用戶輸入時,程序將等待直到用戶返回。DataInputStream讀取不阻止

我的問題是,而不是等待數據變得可用,它讀取值爲0的字節。有沒有辦法阻止,直到數據becoms可用?

readBytes方法在循環中調用。

public byte[] readBytes(){ 
    try{ 

    //read the head int that will be 4 bytes telling the number of bytes that follow containing data 
    byte[] rawLen = new byte[4]; 
    socketReader.read(rawLen); 
    ByteBuffer bb = ByteBuffer.wrap(rawLen); 
    int len = bb.getInt(); 

    byte[] data = new byte[len]; 
    if (len > 0) { 
     socketReader.readFully(data); 
    } 

    return data; 

    } catch (Exception e){ 
    e.printStackTrace(); 
    logError("Failed to read data: " + socket.toString()); 
    return null; 
    } 
} 
+0

擴展'InputStream' **的流將''read''阻塞請參閱https://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html#read() 'readFully'也會阻止 - 也許服務器發送零。 –

+0

你將不得不原諒我,因爲這是我第一次使用套接字。我曾嘗試使用以下內容作爲閱讀器,結果是相同的。 InputStream socketReaderStream = socket.getInputStream(); – user2131323

+0

您對'read()'的使用可能不會讀取全部4個字節。你是否想在那裏使用'readFully()'來確保你讀取所有4個字節? read()的返回值是實際讀取的字節數。 – ck1

回答

2

如果read()返回-1,則該對等體已斷開連接。你沒有處理這種情況。如果您檢測到流結束,則必須關閉連接並停止讀取。目前你無法這樣做。你需要重新考慮你的方法簽名。

您應該使用readInt()而不是那些讀取長度的四行代碼。目前你假設已經讀取了四個字節而沒有實際檢查。 readInt()會爲您檢查。

通過這種方式,您永遠不會與發件人不同步,而發件人目前存在嚴重風險。

+0

它曾經是readInt(),同樣的事情發生了,也試過了readFully – user2131323

+0

和什麼一樣?作爲'read()'返回-1?不可能。 – EJP

+0

不是-1,對不起應該是更清楚,相同的閱讀沒有什麼,即時檢查現在雖然如果連接仍然活躍,服務器不說它的丟失連接 – user2131323