Ошибка StreamCorruptedException

450
09 июля 2017, 11:56

Здравствуйте! Написал небольшую многопользовательскую игру. Когда играет один пользователь (который запустил сервер, хотя точно не проверял), то все нормально, ошибки нет. Если же играют двое, то у первого (сервера) через какое-то (может даже при подключении второго игрока) время вылезает ошибка:

StreamCorruptedException: invalid type code: 00

в строке: while(sock.isConnected()&&(ob1=ois.readObject())!=null)

Почему так? Помогите пожалуйста!

P.S. Я видел на английском Stack Overflow подобные вопросы, но подходящего ответа не нашел.

Сервер:

public class MazeServer implements Runnable{
HashSet clientOutputStreams;
JPanel statistic;
JLabel Label1;
ArrayList<ClientHandler> threads;
int clients;
public ServerSocket serverSocket;
GUI g;
public Player turn;
public MazeServer(GUI g){
    this.g=g;
}
public void stop(){
    try{
        serverSocket.close();
    }catch(IOException e){
        e.printStackTrace();
    }
}
public void run(){
    go();
}
public class ClientHandler implements Runnable{
    ObjectInputStream ois;
    Socket sock=null;
    ObjectOutputStream f;
    String name;
    public ClientHandler(Socket clientSOcket,ObjectOutputStream d){
        try{
            f=d;
            sock=clientSOcket;
            ois=new ObjectInputStream(sock.getInputStream());
        }catch(Exception ex){
            ex.printStackTrace();
        }
    }
    public void run(){
        try{
            System.out.println("Server: Running "+sock);
            Object ob1;
            while(sock.isConnected()&&(ob1=ois.readObject())!=null){
                Message message=(Message)ob1;
                if(message.getType().equals("server")){
                    name=message.getMessage();
                    continue;
                }
                sendMessage(message);
            }
            System.out.println("Server: прочитано");
            if(sock.isConnected()==false){
                System.out.println("Соединение закрыто. ");
                clients=clientOutputStreams.size();
                String clientsString=Integer.toString(clients);
                Label1.setText("Кол-во клиентов: "+clientsString);
            }
        }catch(Exception e){
            e.printStackTrace();
            clientOutputStreams.remove(f);
            clients=clientOutputStreams.size();
            String clientsString=Integer.toString(clients);
            Platform.runLater(new Runnable(){
                public void run(){
                    g.waitPane.deleteFromList(name);
                }
            });
        }
    }
}
public void go(){
    threads=new ArrayList<>();
    clientOutputStreams=new HashSet();
    try{
        serverSocket=new ServerSocket(5001);
        while(true){
            Socket clientSocket=serverSocket.accept();
            ObjectOutputStream oos=new ObjectOutputStream(clientSocket.getOutputStream());
            ClientHandler ch=new ClientHandler(clientSocket,oos);
            Thread t=new Thread(ch);
            threads.add(ch);
            t.setDaemon(true);
            t.start();
            clientOutputStreams.add(oos);
            clients=clientOutputStreams.size();
        }
    }catch(Exception ex){
        ex.printStackTrace();
    }
}
    /*public void Gui() {
    JFrame frame = new JFrame("Сервер");
    JPanel controlButton = new JPanel();
    statistic = new JPanel();
    JButton button1 = new JButton("Стоп");
    JButton button2 = new JButton("Старт");
    Label1 = new JLabel("Кол-во клиентов: "+clients);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    controlButton.add(button1);
    controlButton.add(button2);
    statistic.add(Label1);
    frame.getContentPane().add(BorderLayout.NORTH, controlButton);
    frame.getContentPane().add(BorderLayout.CENTER, statistic);
    frame.pack();
    frame.setSize(400, 300);
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
    }*/
void sendMessage(Message m){
    Iterator<ObjectOutputStream> it=clientOutputStreams.iterator();
    while(it.hasNext()){
        try{
            ObjectOutputStream writer=it.next();
            writer.writeObject(m);
        }catch(Exception ex){
            ex.printStackTrace();
        }
    }
}
void sendPrivateMessage(ObjectOutputStream oos,Message m){
    try{
        oos.writeObject(m);
        oos.flush();
    }catch(IOException e){
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

}

Клиент:

public class Maze{
    public Player progressPlayer;
    GUI gui;
    public HashMap<String,Player> player;
    public Player thisPlayer;
    public Socket sock;
    ObjectOutputStream oos;
    Thread r;
    ObjectInputStream ois;
    String ip;
    int port;
    public ArrayList<MazeTile> startT=new ArrayList<>();
    public Maze(){}
    public Maze(GUI g) throws IOException{
        gui=g;
        thisPlayer=g.player;
        player=new HashMap<String,Player>();
    }

    public void socket(String ip,int port) throws IOException, InterruptedException{
        this.ip=ip;
        this.port=port;
        sock=new Socket();
        sock.connect(new InetSocketAddress(ip,port));
        oos=new ObjectOutputStream(sock.getOutputStream());
        ois=new ObjectInputStream(sock.getInputStream());
        r=new Thread(new IncReader());
        r.setDaemon(true);
        r.start();
        System.out.println("Maze: Соединение установлено.");
        sendMessage(new Message(TypeMessage.player,null,thisPlayer,null,null));
        Thread.sleep(1000);
        sendMessage(new Message(TypeMessage.server,thisPlayer.name,null,null,null));
    }
    public boolean reConnect(){
        try{
            sock.connect(new InetSocketAddress(ip,port),4000);
        }catch(IOException e){
            e.printStackTrace();
        }
        return sock.isConnected();
    }
    public synchronized void sendMessage(Message m){
        try{
            if(sock.isConnected()){
                r.sleep(7);
                oos.writeObject(m);
            }else{
                System.out.println("Соединение не установлено, пытаюсь установить...");
                boolean connect=reConnect();
                if(connect==true){
                    oos.writeObject(m);
                    System.out.println("Соединение установлено (2).");
                }else{
                    System.out.println("Соединение не установлено, проверьте интернет соединение и доступность сервера.");
                }
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    public void close(){
        try{
            r.interrupt();
            sock.close();
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    private void distribution(Message m){
        if(m.getType().equals("stopGame")){
            gui.started=false;
        }
        if(m.getType().equals("lose")){
            player.remove(m.getPlayer().getName());
            sendMessage(new Message(TypeMessage.label,m.getMessage(),null,null,null));
        }
        if(m.getType().equals("label")){
            if(gui.gamePane!=null)
                gui.gamePane.setLabelText(m.getMessage());
            if(gui.isServ)
                sendMessage(new Message(TypeMessage.ta,m.getMessage(),null,null,null));
        }
        if(m.getType().equals("ta")){
            if(gui.gamePane!=null)
                gui.gamePane.setAreaText(m.getMessage());
            if(gui.waitPane!=null){
                gui.waitPane.setAreaText(m.getMessage());
            }
        }
        if(m.getType().equals("player")){
            if(gui.isServ){
                player.put(m.getPlayer().getName(),m.getPlayer());
                System.out.println("Server.Maze: maze.distribution(player) "+player.get(m.getPlayer().getName()).getName()+" размер массива: "+player.size());
                sendMessage(new Message(TypeMessage.players,null,null,null,player));
            }
        }
        if(m.getType().equals("selectTurn")){
            progressPlayer=player.get(m.getPlayer().getName());
            player.get(m.getPlayer().getName()).turn(true);
            if(thisPlayer.turn){
                gui.gamePane.startTimer(gui.turnSecond);
            }
        }
        if(m.getType().equals("completeTurn")){
            if(gui.isServ)
                gui.selectTurn();
        }
        if(m.getType().equals("win")){
            if(gui.isServ)
                sendMessage(new Message(TypeMessage.stopGame,null,null,null,null));
        }
        if(m.getType().equals("turn")){
            player.get(m.getPlayer().getName()).clear();
            player.get(m.getPlayer().getName()).setLayout(m.getPlayer().row,m.getPlayer().column,null);
            player.get(m.getPlayer().getName()).setTurnLayout(m.getPlayer().turnRow,m.getPlayer().turnColumn,null);
            gui.gamePane.mpane.movePlayer(player.get(m.getPlayer().getName()));
            if(gui.isServ&&m.getMessage().equals("win")){return;}
            if(gui.isServ&&m.getMessage().equals("lose")){
                gui.timer.schedule(new TimerTask(){
                    @Override
                    public void run(){
                        sendMessage(new Message(TypeMessage.completeTurn,null,m.getPlayer(),null,null));
                    }
                },1500);
            }else{
                sendMessage(new Message(TypeMessage.completeTurn,null,m.getPlayer(),null,null));
            }
        }
        if(m.getType().equals("map")){
            gui.map=m.getMap();
        }
        if(m.getType().equals("gamePlayers")){
            player=m.getPlayers();
            Player p=player.get(thisPlayer.getName());
            thisPlayer=p;
            if(gui.isServ){
                sendMessage(new Message(TypeMessage.startGame,null,null,null,null));
                gui.timer.schedule(new TimerTask(){
                    @Override
                    public void run(){
                        gui.selectTurn();
                    }
                },4000);
            }
        }
        if(m.getType().equals("players")){
            gui.waitPane.clearList();
            for(String en : m.getPlayers(1)){
                gui.waitPane.addToList(en);
                System.out.println("Maze: distribution(players) на WaitPane добавлен "+en);
            }
        }
        if(m.getType().equals("startGame")){
            gui.started=true;
            gui.startGame();
        }
    }
    class IncReader implements Runnable{
        public void run(){
            message();
        }
        synchronized void message(){
            try{
                Object ob1;
                while(sock.isConnected()&&(ob1=ois.readObject())!=null){
                    Message message=(Message)ob1;
                    System.out.print("Maze: IncReader: тип сообщения: "+message.getType()+"  |  ");
                    Platform.runLater(new Runnable(){
                        public void run(){
                            distribution(message);
                        }
                    });
                }
            }catch(Exception e){
                e.printStackTrace();
                Platform.runLater(new Runnable(){
                    public void run(){
                        Popup p=new Popup();
                        Text t=new Text("Ошибка:\n"+e.toString()+"\n");
                        FlowPane bg=new FlowPane();
                        Button b=new Button("X");
                        b.setPrefSize(30,30);
                        b.setOnAction(new EventHandler<ActionEvent>(){
                            @Override
                            public void handle(ActionEvent event){
                                p.hide();
                            }
                        });
                        bg.setBackground(new Background(new BackgroundFill(Color.WHITE,new CornerRadii(5),Insets.EMPTY)));
                        bg.getChildren().addAll(t,b);
                        p.getContent().addAll(bg);
                        p.show(gui.stage);
                    }
                });
            }
        }
    }
}

Сообщение (Message):

public class Message implements Serializable{
    TypeMessage type;
    Player pl;
    String text;
    String map;
    int[] r;
    int[] c;
    int tr;
    int tc;
    String[] color;
    String[] names;
    public Message(TypeMessage t,String te,Player pl,String map,HashMap<String,Player> pla){
        text=te;
        type=t;
        this.map=map;
        if(pl!=null){
            r=new int[]{pl.row};
            c=new int[]{pl.column};
            tr=pl.turnRow;
            tc=pl.turnColumn;
            color=new String[]{pl.getColor().toString()};
            names=new String[]{pl.getName()};
        }
        if(type.name().equals("players")){
            names=new String[pla.size()];
            int i=0;
            for(Map.Entry<String,Player> en : pla.entrySet()){
                names[i]=en.getKey();
                i++;
            }
        }
        if(type.name().equals("gamePlayers")){
            int i=0;
            color=new String[pla.size()];
            names=new String[pla.size()];
            r=new int[pla.size()];
            c=new int[pla.size()];
            for(Map.Entry<String,Player> en : pla.entrySet()){
                color[i]=en.getValue().getColor().toString();
                names[i]=en.getValue().getName();
                r[i]=en.getValue().row;
                c[i]=en.getValue().column;
                i++;
            }
        }
    }
    public String getMessage(){
        if(text!=null&&!text.isEmpty()){
            return text;
        }else{
            return "Текста нет";
        }
    }
    public HashMap<String,Player> getPlayers(){
        if(type.name().equals("players")){
            getPlayers(1);
        }
        if(type.name().equals("gamePlayers")){
            HashMap<String,Player> players1=new HashMap<>();
            for(int i=0;i<names.length;i++){
                Player p=new Player(Color.valueOf(color[i]));
                p.setLayout(r[i],c[i],null);
                p.name=names[i];
                players1.put(p.getName(),p);
                System.out.println("Message: getPlayers(gamePlayers) "+p.name);
            }
            return players1;
        }
        System.out.println("Message: getPlayers() равен NULL");
        return null;

    }
    public String[] getPlayers(int i){
        return names;
    }
    public String getMap(){
        return map;
    }
    public Player getPlayer(){
        Player pl1=new Player();
        pl1.setLayout(r[0],c[0],null);
        pl1.setTurnLayout(tr,tc,null);
        pl1.setColor(Color.valueOf(color[0]));
        pl1.setName(names[0]);
        return pl1;
    }
    public String getContains(){
        String f="Пусто";
        if(text!=null||pl!=null){
            if(!text.isEmpty()&&pl!=null){
                f="Смешанное";
            }else{
                if(!text.isEmpty()){
                    f="Текстовое";
                }
                if(pl!=null){
                    f="Игрок";
                }
            }
        }
        return f;
    }
    public String getType(){
        return type.name();
    }
}
READ ALSO
Общее и различное в Servlet API и web-socket API

Общее и различное в Servlet API и web-socket API

Как я понимаю что Servlet API, что web-socket API, внутри построены на обычных сокетах(Поправте если я не прав)Но реализация Servlet API построена на идеологии...

244
Как разбить String на отдельные слова в Java?

Как разбить String на отдельные слова в Java?

Всем Привет! У меня есть такая задача, надо разделить строку на слова, записать ее в массив и затем сравнить каждый элемент с каждым в массиве...

476
Создание детектора блатных номеров

Создание детектора блатных номеров

Дано задание : сгенерировать список "блатных" номеров и сделать метод, который будет проверять наличие номера в спискеПрограмма должна работать...

214
Как экспортировать png из zeplin?

Как экспортировать png из zeplin?

Или вообще есть такая возможность в программе? в видео есть https://wwwyoutube

315