StreamCorruptedException: неверный код типа: AC
Моя проблема в том, что когда он пытается прочитать объект во второй раз, он выдает исключение:
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()? Я даже распечатал объект сообщения, который принимается по приведенной ниже строке, и точно такой же, как первый экземпляр, где он работает нормально.
Object buf = myInput.readObject();
Я предполагаю, что есть некоторые проблемы с добавлением, но мне действительно нечего использовать для добавления. Я просто хочу читать свежие строки каждый раз.
Я бы очень признателен за помощь в исправлении этой ошибки. Спасибо.
==================================
До этой одной строки я просто создаю входные и выходные объекты для сокета в методе run(). Объявление объекта вне метода run() в классе: -
@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();
}
}
}
Вы правы; Я не закрываю объект. Я не уверен, как это сделать.
Ответы
Ответ 1
Основная проблема заключается в том, что вы используете новый ObjectOutputStream
для записи в существующий ObjectInputStream
, который вы уже использовали ранее ObjectOutputStream
для записи. Эти потоки имеют заголовки, которые записываются и считываются соответствующими конструкторами, поэтому, если вы создаете еще один ObjectOutputStream
, вы напишете новый заголовок, который начинается с - угадайте, что? - 0xAC,
, а существующий ObjectInputStream
не ожидает другого заголовка в этой точке, поэтому barfs.
В потоке форумов Java, указанном @trashgod, я должен был оставить часть "заново для каждого объекта на обоих концах": это просто расточительно. Используйте один OOS и OIS для жизни сокета и не используйте другие потоки в сокете.
Если вы хотите забыть, что вы написали, используйте ObjectOutputStream.reset().
И не используйте другие потоки или Readers
или Writers
в том же сокете. API-интерфейсы потоков объектов могут обрабатывать все примитивные типы данных Java и все классы Serializable
.
Ответ 2
Столкнувшись с аналогичным исключением при использовании Java 7/8, я решил его, добавив ниже аргумент VM
-Dsun.lang.ClassLoader.allowArraySyntax=true