从 ObjectInputStream [duplicate] 读取时出现意外的 EOF 异常

Unexpected EOF exception when reading from ObjectInputStream [duplicate]

提问人:giannismparous 提问时间:7/11/2022 更新时间:7/11/2022 访问量:892

问:

所以我正在 Android Studio 中制作一个信使应用程序。我基本上在我的电脑上设置了一个服务器(一个用 Java 运行的程序)和一个客户端(android 代码)。这 2 个维护对象输入流和对象输出流。当客户端的代码被执行时(它是一个异步任务),它会将一些东西写入其输出流,这些内容每次都会成功地写入服务器的输入流。但是,当服务器尝试写入其输出流时,消息会成功写入并刷新(我已经检查了之后的代码是否正在运行,因此写入部分没有问题),但是当客户端尝试从输入流中读取时,它会崩溃。奇怪的是,它不会一直发生,而是随机发生的。不知道如何修复它,客户端唯一要做的就是读取布尔值。

错误是这样的:

2022-07-10 21:34:47.823 11035-11084/com.example.smartchatters W/System.err: java.io.StreamCorruptedException: unexpected EOF in middle of data block
2022-07-10 21:34:47.824 11035-11084/com.example.smartchatters W/System.err:     at java.io.ObjectInputStream$BlockDataInputStream.refill(ObjectInputStream.java:2692)
2022-07-10 21:34:47.824 11035-11084/com.example.smartchatters W/System.err:     at java.io.ObjectInputStream$BlockDataInputStream.read(ObjectInputStream.java:2855)
2022-07-10 21:34:47.824 11035-11084/com.example.smartchatters W/System.err:     at java.io.ObjectInputStream$BlockDataInputStream.read(ObjectInputStream.java:2777)
2022-07-10 21:34:47.824 11035-11084/com.example.smartchatters W/System.err:     at java.io.DataInputStream.readFully(DataInputStream.java:198)
2022-07-10 21:34:47.824 11035-11084/com.example.smartchatters W/System.err:     at java.io.DataInputStream.readChar(DataInputStream.java:365)
2022-07-10 21:34:47.824 11035-11084/com.example.smartchatters W/System.err:     at java.io.ObjectInputStream$BlockDataInputStream.readChar(ObjectInputStream.java:2937)
2022-07-10 21:34:47.824 11035-11084/com.example.smartchatters W/System.err:     at java.io.ObjectInputStream.readChar(ObjectInputStream.java:995)
2022-07-10 21:34:47.824 11035-11084/com.example.smartchatters W/System.err:     at com.example.smartchatters.logic.Usernode$Publisher.sendFile(Usernode.java:255)
2022-07-10 21:34:47.824 11035-11084/com.example.smartchatters W/System.err:     at com.example.smartchatters.logic.Usernode$Publisher.run(Usernode.java:217)

服务器的代码(线程,首先执行publisherBrokerHelper(),然后调用sendFiles()):

 public void publisherBrokerHelper() {
        try {
            MultimediaFile item;
            String r = "";
            while (!r.equals("send")) {
                item = (MultimediaFile) in.readObject();
                r = new String(item.FileChunk, StandardCharsets.UTF_8);
                System.out.println("Command: "+r);
                if (r.equals("send")) {
                    receiveFile(item.getName(),item.getExtension(),item);
                }
            }
        } catch (ClassNotFoundException e) {
            System.err.println("PublisherBrokerHelper ClassNotFound error in run.");
            e.printStackTrace();
        } catch (IOException e) {
            System.err.println("Connection with client terminated unexpectedly");
        }
    }

   public void receiveFile(String fileName,String fileExtension, MultimediaFile sendMessage) {
        String topicName=null;
        ProfileName userName=null;
        boolean verification=false;
        try {
            topicName = (String)in.readObject();
            userName = (ProfileName)in.readObject();
            for (int i=0;i<localTopics.size();i++) {
                if (localTopics.get(i).getName().equals(topicName)) {
                    currentTopic=localTopics.get(i);
                    break;
                }
            }
            for (int i=0;i<currentTopic.getSubscribedUsers().size();i++) {
                if (currentTopic.getSubscribedUsers().get(i).getUsername().equals(userName.getUsername())) {
                    verification=true;
                    break;
                }
            }
            System.out.println("WOW");
            System.out.println(verification);
            if (verification)out.writeChar('Y');
//          else out.writeChar('N');
//          out.flush();
            out.writeBoolean(verification);
            out.flush();
            System.out.println("WOW");
        } catch (ClassNotFoundException e1) {
            System.err.println("PublisherBrokerHelper ClassNotFound error in topic name fetch.");
            e1.printStackTrace();
        } catch (IOException e1) {
            System.err.println("PublisherBrokerHelper IO error error in topic name fetch.");
            e1.printStackTrace();
        }
.
.
.
}


客户端代码(异步线程):

 public void sendFile() {
            try {
                MultimediaFile item;
                File file=null;
                if (fileExtension!=null){
                    file = new File(fileName+"."+fileExtension);
                    item = new MultimediaFile(fileName,user,dateCreated,fileExtension, (int) Math.ceil((float)file.length() / 8192), "send".length()+1,0);
                }
                else {
                    item = new MultimediaFile(fileName,user,dateCreated,fileExtension, 0, "send".length()+1,0);
                }
                item.FileChunk = "send".getBytes(StandardCharsets.UTF_8);
                out.writeObject(item);
                out.flush();
                out.writeObject(topicName);
                out.flush();
                out.writeObject(user);
                out.flush();
                System.out.println("in"+in);
                System.out.println("WOW");
//                System.out.println(in.readChar());
//                boolean verification;
//                verification= in.readChar() == 'Y';
                boolean verification=in.readBoolean();
                if (!verification) {
                    //System.out.println("Seems like you are trying to push in a topic that you don't belong");
                    return;
                }
                if (fileExtension!=null) {
                    InputStream FileStream = new FileInputStream(file);
                    int count=1;
                    item = new MultimediaFile(fileName, user, dateCreated,fileExtension, (int) Math.ceil((float)file.length() / 8192), 8192,count);
                    while ((FileStream.read(item.FileChunk)) > 0) {
                        out.writeObject(item);
                        out.flush();
                        //System.out.println("Publisher sent "+item.getChunkId()+" chunk of file :"+ item.getName()+"."+item.getExtension());
                        item = new MultimediaFile(fileName, user, dateCreated,fileExtension, (int) Math.ceil((float)file.length() / 8192), 8192,count+1);
                        count++;
                    }
                    FileStream.close();
                }
            } catch (IOException e) {
                System.err.println("UserNode IO error in sendFile.");
                e.printStackTrace();
            }
        }
Java Android 套接字客户端 -服务器 EOF

评论

1赞 CommonsWare 7/11/2022
ObjectOutputStream不是为在单独的运行时引擎之间传递对象而设计的(JVM 与 Android 的 ART)。我建议你使用更多为该角色设计的东西(JSON、XML、protobuf 等)。
1赞 President James K. Polk 7/11/2022
您的代码与异常不匹配。异常显示 EOF in 但 中没有这样的行 ,它已被注释掉。请仔细检查您的示例和异常/错误是否对应。显示与不同版本代码相对应的异常将使获取答案变得非常困难。readChar()sendFile()
0赞 user207421 7/11/2022
EOFException使用时并不“意外”。当你到达流的尽头时,你会得到的。您需要通过关闭流并退出读取循环来单独捕获它并正常处理它,而不是将其视为错误。ObjectInputStream

答: 暂无答案