2015-06-26 141 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