web-dev-qa-db-ja.com

StreamCorruptedException:無効なタイプコード:AC

私の問題は、2回目にオブジェクトを読み取ろうとすると、例外がスローされることです。

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)

まったく同じオブジェクトメッセージを初めて送信したとき。ただし、同じことを2回実行しようとすると、上記のエラーがスローされます。 readObject()メソッドを再初期化する必要がありますか?下の行で受信されているメッセージオブジェクトも印刷しました。これは、正常に動作する最初のインスタンスとまったく同じです。

Object buf = myInput.readObject();

追加には問題があると仮定していますが、実際には追加する意味がありません。毎回新しい行を読みたいだけです。このバグを修正するのに助けてくれて本当に感謝しています。ありがとうございました。

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

その1行前に、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();
        }
    }
}

あなたが正しい;オブジェクトを閉じません。どうすればいいのかわかりません。

31
leba-lev

根本的な問題は、新しいObjectOutputStreamを使用して、以前のObjectInputStreamを使用して既存のObjectOutputStreamに書き込むことです。これらのストリームには、それぞれのコンストラクターによって読み書きされるヘッダーがあるため、別のObjectOutputStreamを作成すると、新しいヘッダーが作成されます。 -_0xAC,_および既存のObjectInputStreamは、この時点で別のヘッダーを予期していないため、バーフします。

@trashgodが引用したJava Forumsスレッドでは、「両端のオブジェクトごとに新しくする」という部分を省く必要がありました。それは無駄です。ソケットのその他のストリームを使用しないでください。

書いたものを忘れたい場合は、ObjectOutputStream.reset().を使用します

また、同じソケットで他のストリームやReadersまたはWritersを使用しないでください。オブジェクトストリームAPIは、すべてのJavaプリミティブデータ型とすべてのSerializableクラスを処理できます。

71
user207421