The*_*Guy 1 java arrays networking packet datainputstream
我现在正在服务器上玩游戏.服务器的数据包读取循环是阻塞的,并且通常等待直到收到数据包才能继续循环.但是,如果客户端断开连接,DataInputStream将返回单个字节(-1),并且如预期的那样快速连续执行循环.但是,我不使用DataInputStream的read()方法一次读取一个字节,我使用read(byte [])方法将它们一次性读取到一个字节数组中.因此,我无法轻易检测到流是否返回值为-1的单个字节.
可能的解决方案:我可以检查数组的第一个字节是否为-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
}
}
Run Code Online (Sandbox Code Playgroud)
你的理解read(byte[])是不正确的.它没有在数组中设置值-1.
Javadoc说:
返回: 读入缓冲区的总字节数,或者
-1由于已到达流末尾而没有更多数据.
您需要检查返回值:
int bytesRead = input.read(data);
if (bytesRead == -1)
{
// it's end of stream
}
Run Code Online (Sandbox Code Playgroud)
另外,即使只是正常读取数据,也需要检查读取的字节数是否是您请求的字节数.调用read不能保证实际填充您的数组.
您应该看一下readFully()哪个读取完全,并抛出一个EOFException结束流:
从输入流中读取一些字节并将它们存储到缓冲区数组b中.读取的字节数等于b的长度.此方法将阻塞,直到出现下列情况之一:
b.length输入数据的字节是可用的,在这种情况下,进行正常的返回.- 检测到文件结尾,在这种情况下
EOFException抛出一个文件.- 发生I/O错误,在这种情况下,
IOException比其它EOFException异常.