为什么我的ObjectInputStream抛出EOFException?

时间:2014-03-28 03:36:54

标签: java objectinputstream objectoutputstream eofexception custom-object

我正在写一个聊天室代码,每条消息都在客户端和服务器之间来回传递。我已将所有消息转换为序列化对象,并使用它们来回传递信息。不幸的是,这导致在第一次读取对象时抛出EOFException。错误代码如下:

Exception in thread "main" java.io.EOFException
    at java.io.DataInputStream.readInt(Unknown Source)
    at java.io.ObjectInputStream$BlockDataInputStream.readInt(Unknown Source)
    at java.io.ObjectInputStream.readInt(Unknown Source)
    at Serverside.ChatObject.readObject(ChatObject.java:36)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at java.io.ObjectStreamClass.invokeReadObject(Unknown Source)
    at java.io.ObjectInputStream.readSerialData(Unknown Source)
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.readObject(Unknown Source)
    at Clientside.Client.run(Client.java:161)
    at Clientside.Client.main(Client.java:233)

我不确定这是否是由于ObjectOutputStream从未被关闭引起的,但如果是这样,我该如何解决这个问题呢?我是否必须在每次写入一个对象时重新打开流,并且输入流是否可以留在循环中以等待数据?

这是我的自定义对象读/写代码:

    private void writeObject(java.io.ObjectOutputStream stream) throws IOException{
    stream.writeObject(type);
    stream.writeObject(chatroom);
    stream.writeObject(target);
    stream.writeObject(sender);
    stream.writeObject(message);
    stream.writeObject(users);
    stream.close();
}

private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException{
    type = stream.readInt();
    chatroom = stream.readInt();
    target = (String) stream.readObject();
    sender = (String) stream.readObject();
    message = (String) stream.readObject();
    users = (ArrayList<String>) stream.readObject();
    stream.close();
}

这是在服务器端启动线程后的第一个代码。除此之外不可能发生这个问题,因为其他方法还没有被调用的能力。

    public void run(){
        try{
            out = new ObjectOutputStream(socket.getOutputStream());
            in = new ObjectInputStream(socket.getInputStream());

            while(true){
                out.writeObject(new ChatObject(0));
                out.flush();
                info = (ChatObject) in.readObject();
                name = info.getSender();
                if(name == null){
                    return;
                }
                synchronized (names){
                    if(!names.contains(name)){
                        names.add(name);
                        break;
                    }
                }
            }

如果有人认为有必要,我可以根据需要包含更多代码(来自对象或来自客户端/写作方)。

2 个答案:

答案 0 :(得分:3)

快速查看DataInputStream#readIntlink)的javadoc条目告诉我,此方法抛出EOFException(代表文件结束异常)当您尝试阅读的流和来自 int结束时 少于4个字节(由{<1}}组成的<{1}} strong>四个字节)。

您可能需要使用一些阻止的界面,直到流包含足够的数据:)

答案 1 :(得分:1)

如果您使用type = stream.readInt();阅读类型,则应使用stream.writeInt(type);

编写