0

マルチプレイヤーのヘビゲームを開発しています。java.io.StreamCorrupted 例外タイプコード :AC を頻繁に (毎回ではなく) ランダムにスローすることを除いて、ゲームは正常に実行されているようです。同じ完全な StackTrace を以下に示します。

java.io.StreamCorruptedException: invalid type code: AC
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readArray(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.defaultReadFields(Unknown Source)
at java.io.ObjectInputStream.readSerialData(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at mycode.ConnectionManager.otherRunMethod(ConnectionManager.java:231)
at mycode.ConnectionManager$1.run(ConnectionManager.java:289)
at java.lang.Thread.run(Unknown Source)

エラーが生成されるクライアント側のコードを以下に示します。

void otherRunMethod() {
    try {
        while (true) {
            boolean gameup = false;
            objin = new ObjectInputStream(socket.getInputStream());
            Object insnake = objin.readObject();
            if (((Snake) insnake).player.length() >= 9) {
                if (((Snake) insnake).player.substring(0, 8).equals(
                        "Resigned")) {
                    String[] s = ((Snake) insnake).player.split(",");
                    map.remove(s[1]);
                    continue;
                } else if (((Snake)insnake).player.substring(0, 10)
                        .equals("food_eaten")) {
                    String[] s = ((Snake) insnake).player.split(",");
                    Game.foodx = Integer.parseInt(s[1]);
                    Game.foody = Integer.parseInt(s[2]) + 35;
                    objin = new ObjectInputStream(socket.getInputStream());
                    insnake = objin.readObject();
                    if(((Snake)insnake).score>highestscore){
                        highestscore=((Snake)insnake).score;
                        if(highestscore>=100 && highestscore<200)
                            levelUp(2);
                        else if(highestscore>=200){
                            levelUp(4);
                        }
                    }
                    if (s.length == 4) {
                        System.out.println(s[3]);
                        if (s[3].equals("game_up")) {
                            gameup=true;
                        }
                    }
                }
            }
            Snake temp = new Snake((Snake) insnake);
            map.remove(temp.player);
            map.put(temp.player, temp);
            if(temp.gameover){
                allPlayersEliminated();
            }
            findPos();
            game_UpCheck(gameup);
            Thread.sleep(10);
        }
    } catch (java.net.SocketException s) {
        JOptionPane.showMessageDialog(null, "Server Closed", "ERROR",
                JOptionPane.ERROR_MESSAGE);
        System.exit(0);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

これに対応するサーバー側のコードは次のとおりです。

    void relay(Snake move) {
    boolean foodeaten = false;
    Snake snake = move;
    try {
        if (move != null && move.player.length() > 9) {
            if (move.player.equals("food_eaten")) {
                move.player = move.player + ","
                        + (Snakeserver.randomGenerator.nextInt(100) * 6)
                        + ","
                        + (Snakeserver.randomGenerator.nextInt(100) * 6);
                foodeaten = true;
                snake = (Snake) objin.readObject();
                int rows = Snakeserver.score.getModel().getRowCount();
                int row = 1;
                for (int i = 0; i < rows; i++) {
                    if (((Snake) snake).player
                            .equals((String) Snakeserver.score.getModel()
                                    .getValueAt(i, 0))) {
                        row = i;
                        break;
                    }
                }
                if (snake.score >= 300)
                    move.player += "," + "game_up";
                Snakeserver.score.getModel()
                        .setValueAt(snake.score, row, 1);
            } 
        }

        if (move.gameover) {
            int rows = Snakeserver.score.getModel().getRowCount();
            int row = 1;
            for (int i = 0; i < rows; i++) {
                if (snake.player.equals((String) Snakeserver.score
                        .getModel().getValueAt(i, 0))) {
                    row = i;
                    break;
                }
            }
            Object temp = Snakeserver.score.getModel().getValueAt(row,
                    1);
            temp += "  GAME OVER";
            Snakeserver.score.getModel().setValueAt(temp, row, 1);
        }

        for (Snake name : map.keySet()) {
            if (name != null) {
                if (name.player.equals(snake.player)) {
                    name.copyValues(snake);
                }
                objout = new ObjectOutputStream(map.get(name)
                        .getOutputStream());
                objout.writeObject(move);
                objout.flush();
                if (foodeaten) {
                    objout = new ObjectOutputStream(map.get(name)
                            .getOutputStream());
                    objout.writeObject(snake);
                    objout.flush();
                }
            }
        }
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

実際、どこに問題があるのか​​ わからないので、必要以上のコードをダンプした可能性があります。

4

2 に答える 2

0

私も上記で説明したのと同じ例外と問題に直面しましたが、msg(object) の書き込み (送信) 中に、以下のように新しい OutputObjectStream を作成していました。

//client or server side
while(true)
{
    ObjectOutputStream out = new ObjectOutputStream(s.getOutputStream());
    out.writeObject(some_msg_object);
}

/* but while reading(receiving), I was not creating new inputObjectReader
ie */
//on other side
while(true)
Message msgReceived = (Message)inputObjectReader.readObject();

そして、これはまったく同じ教育をもたらしました。

したがって、新しい OutputStream を作成して msg を送信し、新しい InputStream を作成して受信する場合、その逆は、既に作成された同じ OutputStream を使用して送信され、既に作成された InputStream によって受信されます.....

于 2014-02-23T23:09:46.640 に答える