对套接字的java.io.StreamCorruptedException

时间:2013-04-13 09:51:37

标签: java exception serialization java-io objectinputstream

我正在开发一款多人蛇游戏。游戏似乎运行正常,除了它经常(不是每次)随机抛出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();
    }
}

实际上我不知道问题出在哪里,所以我可能会抛出更多不必要的代码。

2 个答案:

答案 0 :(得分:0)

我在挖了几个小时后终于找到了解决问题的方法。 在服务器端代码中,请参阅以下代码:

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();
//rest of code goes here. Closing brackets as above.

如果我写行

 objout = new ObjectOutputStream(map.get(name).getOutputStream());
复合语句前的

if (name.player.equals(snake.player)) {
            name.copyValues(snake);
}

我似乎摆脱了StreamCorrupted Exception。 关于为什么会发生这种情况的任何建议都会受到欢迎。

答案 1 :(得分:0)

我也面临同样的例外和问题,如上所述,是, 在编写(发送)msg(对象)时,我正在创建新的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();

这导致了完全相同的教育,

因此,如果发送msg,通过创建新的OutputStream,通过创建新的InputStream反之接收它,使用已经创建的InputStream发送使用相同的已创建的OutputStream .....