2010-03-06 6 views
26

Моя проблема в том, когда он пытается читать объект во второй раз, он бросает исключение: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(); 
     } 
    } 
} 

Вы правы; Я не закрываю объект. Я не знаю, как это сделать.

+0

Я не уверен, где закрыть объект –

+0

NB Вы должны поймать EOFException и не относиться к ней как ошибка: не записывайте и не печатайте трассировку стека; просто позвольте ему закончить цикл чтения. Я не знаю, почему вы ловите UnknownHostException, где вы находитесь: его нельзя выбросить из соответствующего блока try. Сон() просто буквально пустая трата времени. Убери это. – EJP

ответ

54

Основная проблема заключается в том, что вы используете новый ObjectOutputStream для записи существующего ObjectInputStream, который вы уже использовали до ObjectOutputStream для записи. Эти потоки имеют заголовки, которые записываются и считываются соответствующими конструкторами, поэтому, если вы создаете еще один ObjectOutputStream, вы напишете новый заголовок, который начинается с - угадайте, что? - 0xAC,, а существующий ObjectInputStream не ожидает другого заголовка в этот момент, так что он будет barfs.

В ветке форума Java, процитированном @trashgod, я должен был оставить часть «заново для каждого объекта на обоих концах»: это просто расточительно. Используйте один OOS и OIS для жизни сокета и не используйте другие потоки в сокете.

Если вы хотите забыть, что вы написали, используйте ObjectOutputStream.reset().

И не используйте никакие другие потоки или Readers или Writers на том же сокете. API-интерфейсы потоков объектов могут обрабатывать все примитивные типы данных Java и все классы Serializable.

+1

+1 @rookie: Это правильный ответ, и из исходного источника! :-) – trashgod

+0

@EJP evrytime Я запускаю код, созданный новый OOS и OIS. как мне это удается? –

+0

@AkhilKNambiar Я не знаю, о чем вы спрашиваете меня, о чем еще не сказано выше. – EJP

-1

Столкнувшись аналогичное исключение при использовании Java 7/8, я решил ее, добавив ниже VM аргумент

-Dsun.lang.ClassLoader.allowArraySyntax=true 
+0

«Аналогичный» - это не то же самое. Это не решает проблему, отправленную OP. – EJP

Смежные вопросы