Как исправить java EOFException, используя ObjectInbputStreem в java сети - PullRequest
0 голосов
/ 30 апреля 2020

Я хочу отправить несколько объектов по сети. Моя сеть я сделал это используя DatagramSocket, DatagramPacket, ByteArrayInputStream, ObjectInputStream, ByteArrayOutputStream и ObjectOutputStream. Когда я пытался отправить объект по сети, я получил java.io.EOFException, а когда я обработал это исключение, используя try and catch, я потерял свой объект.

Сторона сервера

public class GameServer extends Thread {
private DatagramSocket socket;
private DatagramPacket packet;
private byte[] data;
private ByteArrayInputStream bais;
private ObjectInputStream ois;
private ByteArrayOutputStream baos;
private ObjectOutputStream oos;
private Game game;

public GameServer() {
    try {
        this.socket = new DatagramSocket(1331);
    }
    catch (SocketException e) {
        e.printStackTrace();
    }
    start();
}

@Override
public void run() {
    while (true) {
        data = new byte[6400];
        packet = new DatagramPacket(data, data.length);
        Object object = receive();

        if (object instanceof String) {
            String message = (String) object;
            System.out.println("CLIENT [ " + packet.getAddress().getHostAddress() + " : " + packet.getPort() + " ] >> " + message.trim());
            if (message.equalsIgnoreCase("start")) {
                game = new Game("Tankies", 1200, 700);
                sendObject(game);
            }
        }
        else if (object instanceof State) {
            System.out.println("got state");
        }
        else if (object instanceof Player)
            System.out.println("hi player");

    }
}

private Object receive() {
    bais = new ByteArrayInputStream(data);
    try {
        socket.receive(packet);
        ois = new ObjectInputStream(new BufferedInputStream(bais));
        return ois.readObject();
    } catch (EOFException e) {
        System.out.println("SERVER Got EOFException");
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }

    return null;
}

private void sendData(byte[] data, InetAddress ipAddress, int port) {
    DatagramPacket packet = new DatagramPacket(data, data.length, ipAddress, port);
    try {
        this.socket.send(packet);
    }
    catch (IOException e) {
        e.printStackTrace();
    }
}

private void sendObject(Object object) {
    baos = new ByteArrayOutputStream(6400);
    oos = null;
    try {
        oos = new ObjectOutputStream(baos);
        oos.writeObject(object);
    }
    catch (IOException e) {
        e.printStackTrace();
    }
    sendData(baos.toByteArray(), packet.getAddress(), packet.getPort());
}

}

Клиентская сторона

public class GameClient extends Thread implements Serializable {

private InetAddress ipAddress;
private transient DatagramSocket socket;
private transient DatagramPacket packet;
private byte[] data;
private transient ByteArrayInputStream bais;
private transient ObjectInputStream ois;
private transient ByteArrayOutputStream baos;
private transient ObjectOutputStream oos;
private Game game;


public GameClient(String ipAddress) {
    try {
        this.socket = new DatagramSocket();
    }
    catch (SocketException e) {
        e.printStackTrace();
    }
    try {
        this.ipAddress = Inet4Address.getByName(ipAddress);
    }
    catch (UnknownHostException e) {
        e.printStackTrace();
    }
    start();
}

@Override
public void run() {
    while (true) {
        data = new byte[6400];
        packet = new DatagramPacket(data, data.length);
        Object object = receive();

        if (object instanceof String) {
            System.out.println("SERVER >> " + object);
        }
        else if (object instanceof Game) {
            this.game = (Game) object;
            this.game.setClient(this);
            this.game.start();
        }

    }
}

private Object receive() {
    bais = new ByteArrayInputStream(data);
    try {
        socket.receive(packet);
        ois = new ObjectInputStream(new BufferedInputStream(bais));
        return ois.readObject();
    }
    catch (IOException | ClassNotFoundException e) {
        e.printStackTrace();
    }
    return null;
}

private void sendData(byte[] data) {
    DatagramPacket packet = new DatagramPacket(data, data.length, ipAddress, 1331);
    try {
        this.socket.send(packet);
    }
    catch (IOException e) {
        e.printStackTrace();
    }
}

public void sendObject(Object object) {
    baos = new ByteArrayOutputStream(6400);
    oos = null;
    try {
        oos = new ObjectOutputStream(baos);
        oos.writeObject(object);
    }
    catch (IOException e) {
        e.printStackTrace();
    }
    sendData(baos.toByteArray());
}

}

Код для отправки объекта на сервер

public class MultiplayerState extends State{
private World world;
private Tank myTank, playerTank;

public MultiplayerState(Handler handler) {
    super(handler);
}

@Override
public void startState() {
    world = new World(handler,"res/worlds/world1.txt");
    handler.setWorld(world);
    myTank = new Tank(handler, world.getSpawnX(), world.getSpawnY());
    handler.getGame().getRender().addObject(world);
    handler.getGame().getRender().addObject(myTank);
    world.start();
    myTank.start();
    handler.getGame().getClient().sendObject(handler.getGame().getPlayer());
}

}

handler.getGame().getClient().sendObject(handler.getGame().getPlayer());

Эта строка чтобы отправить player на сервер .. некоторые пояснения о коде .. это игра, использующая многопоточность в java, и я хочу создать простую сеть, чтобы два разных ноутбука играли в эту игру онлайн, потому что я создал эту сеть. Я создал класс Handler, это класс для управления всей игрой, используя экземпляр объекта Handler класса, я могу получить что-нибудь в игре и хочу получить экземпляр объекта класса Player, чтобы отправить его на сервер, потому что я хочу сделать что-нибудь, чтобы сделать игру онлайн.

1 Ответ

0 голосов
/ 01 мая 2020

Я решил это исключение, сделав GameClient объект в Game классе transient, потому что я не хочу его сериализовать. Я хочу использовать этот объект для отправки чего-либо на сервер из внутреннего объекта Game.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...