web-dev-qa-db-fra.com

StreamCorruptedException: code de type non valide: AC

Mon problème est quand il essaie de lire l'objet la deuxième fois, il lève l'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)

La première fois que j'envoie exactement le même message d'objet; cependant, lorsque j'essaie de faire la même chose la deuxième fois, cela renvoie l'erreur ci-dessus. Dois-je ré-initialiser la méthode readObject ()? J'ai même imprimé l'objet de message qui est reçu par la ligne ci-dessous et c'est exactement la même chose que la première instance où cela fonctionne bien.

Object buf = myInput.readObject();

Je suppose qu'il y a un problème avec l'ajout, mais je n'ai vraiment aucune utilité pour l'ajout. Je veux juste lire une nouvelle ligne à chaque fois. J'apprécierais vraiment une aide pour corriger ce bogue. Je vous remercie.

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

Avant cette seule ligne, je crée simplement les objets d'entrée et de sortie pour le socket dans la méthode run (). La déclaration d'objet est en dehors de la méthode run () dans la classe: -

@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();
        }
    }
}

Tu as raison; Je ne ferme pas l'objet. Je ne sais pas comment faire ça.

31
leba-lev

Le problème sous-jacent est que vous utilisez un nouveau ObjectOutputStream pour écrire dans un ObjectInputStream existant que vous avez déjà utilisé un ObjectOutputStream antérieur pour écrire dans. Ces flux ont des en-têtes qui sont écrits et lus par les constructeurs respectifs, donc si vous créez un autre ObjectOutputStream vous écrirez un nouvel en-tête, qui commence par - devinez quoi? - 0xAC, Et le ObjectInputStream existant ne s'attend pas à un autre en-tête à ce stade, donc il barfs.

Dans le fil de discussion Java Forums cité par @trashgod, j'aurais dû laisser de côté la partie "à nouveau pour chaque objet aux deux extrémités": c'est juste du gaspillage. Utilisez un seul OOS et OIS pour la vie du socket, et n'utilisez aucun autre flux sur le socket.

Si vous voulez oublier ce que vous avez écrit, utilisez ObjectOutputStream.reset().

Et n'utilisez pas d'autres flux ou Readers ou Writers sur le même socket. Les API de flux d'objets peuvent gérer tous les types de données primitifs Java Java et toutes les classes Serializable).

71
user207421