客户端服务器 EOF 错误

Client Server EOF Error

我的应用程序使用 DataInputStream 和 DataOutputStream 在服务器和客户端之间进行通信。客户端将从网站向我的应用程序发出请求,因此我创建了一个测试客户端来测试可能来自该网站的输入。

我决定使用的方法是客户端先发送一个整数,决定要发送的数据大小,然后再发送数据。因此,我正在测试此方法,它适用于第一个数据字符串,但不适用于第二个数据字符串,并且在第二次尝试时给了我一个 EOF 错误。我明白为什么它给了我一个 EOF,因为客户端关闭了连接,但我仍然没有读取传入的字节,所以流应该还有更多要读取的内容。

客户代码:

Socket socket = new Socket("127.0.0.1", 9000);
DataOutputStream os = new DataOutputStream(socket.getOutputStream());
os.writeInt("Test String".length());
os.write("Test String".getBytes());
os.flush();
os.writeInt("String".length());
os.write("String".getBytes());
os.flush();
os.close();
socket.close();

服务器代码:

byte[] data;

try{
    DataInputStream input = new DataInputStream(client.getInputStream());
    DataOutputStream output = new DataOutputStream(client.getOutputStream());
        client.setSoTimeout(SOCKET_TIMEOUT);

    logger.log(Level.INFO, "Client connected with IP: " + client.getInetAddress());

    data = readNextPacket(input);
    if(!(new String(data).contains(PROTOCOL_HEADER)))
        throw new IOException("Invalid request from client.");
    else
        logger.log(Level.INFO, "Valid header: " + new String(data));

    data = readNextPacket(input);
    logger.log(Level.INFO, new String(data));
}catch(IOException e){
    logger.log(Level.SEVERE, e.getMessage(), e);
}finally{
    try {
        client.close();
    } catch (IOException e) {
        logger.log(Level.SEVERE, e.getMessage(), e);
    }
    logger.log(Level.INFO, "FINISHED");
}

readNextPacket 方法:

private byte[] readNextPacket(DataInputStream stream) throws IOException{
    int bytesToRead = stream.readInt();
    ByteArrayOutputStream os = new ByteArrayOutputStream();

    if(bytesToRead <= MAX_BYTES){
        byte[] data = new byte[bytesToRead];

        while(stream.read(data) != -1 && os.size() < bytesToRead){
            os.write(data);
        }
    }

    return os.toByteArray();
}

堆栈跟踪:

java.io.EOFException
at java.io.DataInputStream.readInt(DataInputStream.java:392)
at com.schmidt73.bidwriter.handlers.SocketHandler.readNextPacket(SocketHandler.java:1)
at com.schmidt73.bidwriter.handlers.SocketHandler.parse(SocketHandler.java:16)
at com.schmidt73.bidwriter.handlers.SocketHandler.start(SocketHandler.java:43)
at com.schmidt73.bidwriter.BidWriter.main(BidWriter.java:21)

好吧,如果第一次没有读取整个缓冲区,基本上我的 readNextPacket() 方法会读取比指定的更多的数据。因此,我更改了一些代码以通过添加偏移量并减去我已经读取到 read() 方法的数量来修复它。但是,我意识到这基本上是在复制 readFully() 方法,没有理由这样做,所以我只是将其实现到 readNextPacket() 方法中。

这是新的工作代码:

private byte[] readNextPacket(DataInputStream stream) throws IOException{
    int bytesToRead = stream.readInt();
    byte[] data = new byte[bytesToRead];

    stream.readFully(data);
    return data;
}