2015-06-26 67 views
1

我正在爲遊戲的服務器上工作。服務器的數據包讀取循環處於阻塞狀態,通常會一直等到收到數據包才能繼續循環。但是,如果客戶端斷開連接,則DataInputStream將返回一個單字節(-1),並按預期順序快速連續執行循環。但是,我不使用DataInputStream的read()方法一次讀取一個字節,我使用read(byte [])方法一次將它們讀入一個字節數組中。因此,我不容易檢測到流是否返回值爲-1的單個字節。檢測DataInputStream流結束

可能的解決方案:我可以檢查數組的第一個字節是否爲-1,如果是,則遍歷數組以查看數組的其餘部分是否爲零。然而,這樣做效率極低,我認爲這會隨着客戶數量的增加而影響性能。

這是我的包讀取環路的簡化版本:

while (!thread.isInterrupted() && !isDisconnected()) 
{ 
    try 
    { 
     byte[] data = new byte[26]; 
     data = new byte[26]; 

     input.read(data); 

     //Need to check if end of stream here somehow 
     Packet rawPacket = Packet.extractPacketFromData(data); //Constructs packet from the received data 

     if(rawPacket instanceof SomePacket) 
     { 
      //Do stuff with packet 
     } 
    } 
    catch(IOException e) 
    { 
     disconnectClient(); //Toggles flag showing client has disconnected 
    } 
} 
+1

你應該看'readFully'順便說一句。 –

回答

3

你的read(byte[])的理解不正確。它不會將數組中的值設置爲-1

的Javadoc說:

返回: 字節總數讀入緩衝區,或-1如果沒有更多的數據,因爲數據流的末尾已到達。

您需要檢查返回值:

int bytesRead = input.read(data); 
if (bytesRead == -1) 
{ 
    // it's end of stream 
} 

作爲一個側面說明,即使只是讀數據正常,你就需要檢查讀取的字節數是您所請求的字節數。對read的調用並不能保證實際填滿你的數組。

你應該看看readFully()其中不充分讀取,並且對於流的末尾拋出EOFException

讀取從輸入流中,並將它們存儲到緩衝區數組b一些字節。讀取的字節數等於b的長度。 此方法一直阻塞的出現下列情況之一:輸入數據的

  • b.length字節是可用的,在這種情況下,正常返回。
  • 檢測到文件結尾,在這種情況下會引發EOFException
  • 發生I/O錯誤,在這種情況下,會拋出除EOFException之外的IOException