StreamCorruptedException:无效类型代码:AC

2022-01-30 00:00:00 multithreading object streaming java

我的问题是当它第二次尝试读取对象时,它会抛出异常:

My problem is when it tries to read the object the second time, it throws the exception:

java.io.StreamCorruptedException: invalid type code: AC
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1356)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
    at Client.run(BaseStaInstance.java:313)

java.io.StreamCorruptedException: invalid type code: AC
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1356)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
    at Client.run(BaseStaInstance.java:313)

我第一次发送完全相同的对象消息;但是,当我第二次尝试做同样的事情时,它会抛出上面的错误.我需要重新初始化 readObject() 方法吗?我什至打印出了下面一行接收到的消息对象,它与它工作正常的第一个实例完全相同.

The first time I send the exact same object message; however, when I try doing the same thing the second time, it throws the error above. Do I need to re-intialize the readObject() method? I even printed out the message object that is being received by the line below and its exact the same as the first instance where it works ok.

Object buf = myInput.readObject();

我假设追加有一些问题,但我真的没有用追加.我只想每次都读一个新行.我真的很感激修复这个错误的一些帮助.谢谢.

I'm assuming there's some problem with appending, but I really have no use for appending. I just want to read a fresh line everytime. I'd really appreciate some help in fixing this bug. Thank you.

===================================

==================================

在这一行之前,我只是在 run() 方法中为套接字创建输入和输出对象.对象声明在类中的run()方法之外:-

Before that one line, I'm just creating the input and output objects for the socket in the run() method. The object declaration is outside the run() method in the class:-

@Override
public void run() {
    try {
        sleep((int) 1 * 8000);
    } catch (Exception e) {
        e.printStackTrace();
    }

    try {
        //Creating input and output streams to transfer messages to the server
        myOutput = new ObjectOutputStream(skt.getOutputStream());
        myInput = new ObjectInputStream(skt.getInputStream());
        while (true) {
            buf = myInput.readObject();
        }
    } catch (UnknownHostException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

你是对的;我不关闭对象.我不知道该怎么做.

You're right; I don't close the object. I'm not sure how to do that.

推荐答案

潜在的问题是你正在使用一个新的 ObjectOutputStream 来写入一个你已经使用过的流 要写入的 ObjectOutputStream.这些流具有由各自的构造函数写入和读取的标头,因此如果您创建另一个 ObjectOutputStream 您将编写一个新的标头,该标头以 - 你猜怎么着?- 0xAC, 和现有的 ObjectInputStream 在这一点上并不期待另一个标题,所以它会出错.

The underlying problem is that you are using a new ObjectOutputStream to write to a stream that you have already used a prior ObjectOutputStream to write to. These streams have headers which are written and read by the respective constructors, so if you create another ObjectOutputStream you will write a new header, which starts with - guess what? - 0xAC, and the existing ObjectInputStream isn't expecting another header at this point so it barfs.

在@trashgod 引用的Java 论坛线程中,我应该省略关于在两端为每个对象重新创建"的部分:这只是浪费.在套接字的整个生命周期内使用单一的 OOS 和 OIS,并且不要在套接字上使用任何其他流.

In the Java Forums thread cited by @trashgod, I should have left out the part about 'anew for each object at both ends': that's just wasteful. Use a single OOS and OIS for the life of the socket, and don't use any other streams on the socket.

如果你想忘记你写的内容,使用 ObjectOutputStream.reset().

If you want to forget what you've written, use ObjectOutputStream.reset().

并且不要在同一个套接字上使用任何其他流或 ReadersWriters.对象流 API 可以处理所有 Java 原始数据类型和所有 Serializable 类.

And don't use any other streams or Readers or Writers on the same socket. The object stream APIs can handle all Java primitive datatypes and all Serializable classes.

相关文章