1

我正在编写一个聊天室代码,每条消息都在客户端和服务器之间不断地来回发送。我已将所有消息都制成序列化对象,并使用它们来回传递信息。不幸的是,这导致在第一次读取对象时抛出 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;
                    }
                }
            }

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

4

2 回答 2

3

快速查看DataInputStream#readInt( linkEOFException ) 的javadoc条目告诉我,当您尝试读取的流和来自小于4 个字节的流结束时(正在制作Java四个字节)。intint

您可能需要使用一些阻塞的接口,直到流包含足够的数据:)

于 2014-03-28T03:50:03.977 回答
1

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

于 2014-03-28T05:03:34.100 回答