客户端服务器EOF错误

时间:2015-01-21 23:30:49

标签: java sockets

我的应用程序使用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)

1 个答案:

答案 0 :(得分:0)

好的,基本上如果第一次没有读取整个缓冲区,我的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;
}