流损坏的异常无效代码:00

时间:2014-05-11 20:51:35

标签: java serialization

package com.common.net;

import java.io.EOFException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.StreamCorruptedException;
import java.net.Socket;
import java.net.SocketException;
import java.util.HashMap;
import java.util.Random;

public abstract class PacketCommunicator implements Runnable {

    private Object lastCommandSent;
    private Object lastCommandReceived;
    private Object lastPacketReceived;
    private Object lastPacketSent;

    protected ObjectInputStream in;
    protected ObjectOutputStream out;
    protected Socket socket;
    private boolean connected;
    protected boolean encryptionEnabled = false;
    protected String key = "default";

    public HashMap<String, Object> data;

    protected int sentPackets = 0;
    protected int receivedPackets = 0;

    public String getIP() {
        return socket.getInetAddress().toString();
    }

    public abstract void disconnect();

    public abstract void broadcast(String cmd, String data);

    public abstract void broadcast(Object packet);

    /**
     * This is used for the LPacket system which is not recommended for
     * sensitive data since LPacket's can be decompiled and the functions for
     * both server and client are visible.
     * 
     * @param packet
     */
    public abstract void packetReceived(Object packet);

    /**
     * This is good for sensitive data
     * 
     * @param packetID
     *            ID of packet
     * @param cmd
     *            Labeling command
     * @param data
     */
    public abstract void packetReceived(String cmd, String data);

    public void toggleEncryption() {
        encryptionEnabled = !encryptionEnabled;
    }

    public boolean isConnected() {
        return connected;
    }

    public void flush() {
        try {
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Sends the LPacket to this client
     * 
     * @param packet
     */
    public void sendPacket(Object packet) {
        try {
            sentPackets++;
            out.flush();
            out.writeObject(packet);
            this.lastPacketSent = packet;
            out.flush();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void sendPacket(String cmd, String data) {
        try {

            sentPackets++;

            String s = cmd + ":" + sentPackets + "::" + data;
            out.flush();
            if (encryptionEnabled) {
                out.writeObject(encrypt(key, s));
            } else {
                out.writeObject(s);
            }
            out.flush();
            lastCommandSent = s;

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // Constructor class for game client
    public PacketCommunicator(String server, int port) throws IOException {
        this(new Socket(server, port), false);
    }

    /**
     * 
     * @param socket
     * @param onServer
     *            The Packet Communicator on the server MUST create the input
     *            stream first This constructor is used for the server
     */
    public PacketCommunicator(Socket socket, boolean onServer) {
        this.socket = socket;
        data = new HashMap<String, Object>();

        try {

            if (onServer) {
                in = new ObjectInputStream(socket.getInputStream());
                out = new ObjectOutputStream(socket.getOutputStream());
            } else {
                out = new ObjectOutputStream(socket.getOutputStream());
                in = new ObjectInputStream(socket.getInputStream());
            }

            connected = true;

        } catch (IOException e) {
            e.printStackTrace();
        }

        Thread t = new Thread(this);
        t.start();

    }

    /*
     * @param Manually closes the connection
     */
    public void closeConnection() {
        connected = false;
        disconnect();
        try {
            out.flush();
            out.close();
            in.close();
            socket.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        while (this.isConnected()) {
            try {

                Object packet = in.readObject(); <---Line 174
                receivedPackets++;
                if (packet instanceof String) {
                    this.lastCommandReceived = packet;
                    String packetString = packet.toString();
                    if (encryptionEnabled) {
                        packetString = decrypt(key, packetString);
                    }

                    String cmd = packetString.substring(0, packetString.indexOf(":"));

                    int packetID = Integer.parseInt(packetString.substring(packetString.indexOf(":") + 1,
                            packetString.indexOf("::")));

                    String data = packetString.substring(packetString.indexOf("::") + 2);

                    // FServer.log(packetString);
                    if (packetID == receivedPackets) {

                    } else {
                    }

                    packetReceived(cmd, data);
                } else {
                    this.lastPacketReceived = packet;
                    this.packetReceived(packet);
                }
            } catch (StreamCorruptedException e) {
                connected = false;
                e.printStackTrace();
            } catch (EOFException e) {
                // This usually happens when someone manually disconnects,
                // really not too big of an issue
                connected = false;
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (SocketException e) {
                // Closed client
                connected = false;
            } catch (IOException e) {
                connected = false;
                e.printStackTrace();
            }
        }
        System.out.println("Last packet sent: " + lastPacketSent);
        System.out.println("Last packet received: " + lastPacketReceived);

        System.out.println("Last command sent: " + lastCommandSent);
        System.out.println("Last command received: " + lastCommandReceived);
        disconnect();
    }

    public static String encrypt(String key, String text) {
        long finalKey = 0;
        for (int i = 0; i < key.length(); i++) {
            long tempKey = key.charAt(i);
            tempKey *= 128;
            finalKey += tempKey;
        }
        Random generator = new Random(finalKey);
        String returnString = "";
        for (int i = 0; i < text.length(); i++) {
            if (text.charAt(i) == ' ') {
                returnString += text.charAt(i);
            } else {
                int temp = text.charAt(i);
                temp += generator.nextInt(95);
                if (temp > 126) {
                    temp -= 95;
                }
                returnString += (char) temp;
            }
        }
        return returnString;
    }

    public static String decrypt(String key, String text) {
        long finalKey = 0;
        for (int i = 0; i < key.length(); i++) {
            long tempKey = key.charAt(i);
            tempKey *= 128;
            finalKey += tempKey;
        }
        Random generator = new Random(finalKey);
        String returnString = "";
        for (int i = 0; i < text.length(); i++) {
            if (text.charAt(i) == ' ') {
                returnString += text.charAt(i);
            } else {
                int temp = text.charAt(i);
                temp -= generator.nextInt(95);
                if (temp < 36) {
                    temp += 95;
                }
                if (temp > 126) {
                    temp -= 95;
                }
                returnString += (char) temp;
            }
        }
        return returnString;
    }

}


java.io.StreamCorruptedException: invalid type code: 00
    at java.io.ObjectInputStream$BlockDataInputStream.readBlockHeader(Unknown Source)
    at java.io.ObjectInputStream$BlockDataInputStream.refill(Unknown Source)
    at java.io.ObjectInputStream$BlockDataInputStream.read(Unknown Source)
    at java.io.DataInputStream.readInt(Unknown Source)
    at java.io.ObjectInputStream$BlockDataInputStream.readInt(Unknown Source)
    at java.io.ObjectInputStream.readInt(Unknown Source)
    at java.util.ArrayList.readObject(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at java.io.ObjectStreamClass.invokeReadObject(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.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 com.common.net.PacketCommunicator.run(PacketCommunicator.java:174)
    at java.lang.Thread.run(Unknown Source)

基本上,有时候。我的意思是有时(25%的时间)会出现此错误。 当我尝试从服务器发送它时会发生这种情况:

public void teleportToMap(String mapName, int tileX, int tileY) {
    player.map = mapName;
    currentMap = Server.mapHandler.getMap(mapName);

    MapPacket mp = new MapPacket(currentMap, tileX, tileY);
    sendPacket(mp);

}

现在这里是MapPacket的片段。 MapPacket扩展了PacketToClient,当从objectinputstream接收时,它基本上只调用PacketToClient上的applyToClient。

package com.common.packet.packets.client;

import com.badlogic.gdx.Gdx;
import com.client.Forest;
import com.client.net.ServerConnection;
import com.client.scenes.GameScene;
import com.common.map.Map;
import com.common.movable.Movable;
import com.common.packet.PacketToClient;

import java.util.ArrayList;

public class MapPacket extends PacketToClient {

    private static final long serialVersionUID = 1L;

    String mapName;
    ArrayList<Movable> ground;

    int tileX, tileY;

    public MapPacket(Map map, int tileX, int tileY) {
        this.mapName = map.name;
        this.ground = map.getGround();
        this.tileX = tileX;
        this.tileY = tileY;
    }

    @Override
    public void applyPacketToClient(ServerConnection server) {
        Gdx.app.postRunnable(new Runnable() {
            public void run() {
                GameScene.currentMap = null;
                GameScene.mapRenderer.setCurrentMap(null);
                Map map = ServerConnection.loadMapFromServer(mapName);
                map.setGround(ground);
                GameScene.mapRenderer.setCurrentMap(map);
                GameScene.currentMap = map;
                Forest.player.setTilePosition(tileX, tileY);
            }
        });
    }

}

我从中做了很多研究,但我一直很冷淡。我偶尔也会获得Stream活动异常。

1 个答案:

答案 0 :(得分:1)

我会说你在两个或多个线程中同时写入或读取流。这是&#39; stream active&#39;的唯一解释,它也可以解释另一个问题。

注意:您不需要以不同顺序创建流的业务。始终首先创建ObjectOutputStream。您应该在Runnable的run()方法中创建这些流,而不是在您执行此操作的位置:它涉及阻止I / O,这只应该在该线程中完成。