如何在SocketServer和客户端之间发送“ PlayerData”

时间:2019-05-08 16:30:17

标签: java sockets javafx serversocket

我正在开发MTG / Hearthstone类型的纸牌游戏,但是服务器与客户端之间的通信出现问题。

我已经看过教程和项目,但是它们还没有帮助。客户端经常崩溃,或者在Controller中设置不正确。

服务器:

package server;

import game.GameData;
import game.PlayerData;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

public class ServerTest implements Runnable {

    private int port;
    private boolean running, gameStarted;
    private ArrayList<Socket> players;
    private GameData gameData;

    public ServerTest(int port){
        this.port = port;
        this.running = false;
        this.gameStarted = false;
        gameData = new GameData();
    }

    public Socket waitForConnection(ServerSocket serverSocket) {
        try {
            Socket socket = serverSocket.accept();
            PlayerData playerData = readData(socket);
            System.out.println("Player connected: " + playerData.getName());
            gameData.getPlayers().add(playerData);
            sendData(socket, playerData);
            return socket;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public PlayerData readData(Socket socket){
        try {
            ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
            return (PlayerData) objectInputStream.readObject();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public void sendData(Socket socket, PlayerData playerData){
        try {
            ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream());
            outputStream.writeObject(playerData);
            outputStream.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void stop() {
        running = false;
    }

    @Override
    public void run() {
        running = true;
        int counter = 0;

        try {
            ServerSocket serverSocket = new ServerSocket(port);
            players = new ArrayList<Socket>();
            while (running) {
                if(!gameStarted) {
                    if (gameData.getPlayers().size() < 2) {
                        players.add(waitForConnection(serverSocket));
                    }
                    if (gameData.getPlayers().size() == 2) {
                        gameData.drawCards();
                        gameData.getPlayers().get(0).setOpponent(gameData.getPlayers().get(1));
                        gameData.getPlayers().get(1).setOpponent(gameData.getPlayers().get(0));
                        gameData.getPlayers().set(0, readData(players.get(0)));
                        gameData.getPlayers().set(1, readData(players.get(1)));
                        sendData(players.get(0), gameData.getPlayers().get(0));
                        sendData(players.get(1), gameData.getPlayers().get(1));
                        gameStarted = true;
                        gameData.getPlayers().get(0).setStarted(true);
                        gameData.getPlayers().get(1).setStarted(true);
                        System.out.println("Game started");
                    }
                } else {

                    Thread.sleep(500);
                    gameData.getPlayers().set(0, readData(players.get(0)));
                    gameData.getPlayers().set(1, readData(players.get(1)));
                    gameData.getPlayers().get(0).setOpponent(gameData.getPlayers().get(1));
                    gameData.getPlayers().get(1).setOpponent(gameData.getPlayers().get(0));
                    sendData(players.get(0), gameData.getPlayers().get(0));
                    sendData(players.get(1), gameData.getPlayers().get(1));
                    /*
                    sendData(players.get(counter), gameData.getPlayers().get(counter));
                    gameData.getPlayers().set(counter, readData(players.get(counter)));
                    if(counter == 0) {
                        gameData.getPlayers().get(1).setOpponent(gameData.getPlayers().get(0));
                        sendData(players.get(1), gameData.getPlayers().get(1));
                        counter = 1;
                    } else {
                        gameData.getPlayers().get(0).setOpponent(gameData.getPlayers().get(1));
                        sendData(players.get(0), gameData.getPlayers().get(0));
                        counter = 0;
                    }*/
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

客户:

package client;

import game.GameData;
import game.PlayerData;

import java.io.*;
import java.net.Socket;
import java.net.UnknownHostException;

public class ClientTest implements Runnable{

    private int port;
    private String host;
    private PlayerData playerData;
    private GameData gameData;
    private Socket socket;
    private boolean running;

    public ClientTest(int port, String host, String name) {
        this.port = port;
        this.host = host;
        playerData = new PlayerData(name);
        running = false;
    }

    public void connectToServer(){
        try {
            socket = new Socket(host, port);
            sendPlayerData(socket, playerData);
            readGameData(socket);
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void disconnectFromServer(){
        try {
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void sendPlayerData(Socket socket, PlayerData playerData){
        try {
            ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream());
            outputStream.writeObject(playerData);
            outputStream.flush();
        } catch (IOException e) {
            disconnectFromServer();
        }
    }

    public PlayerData readGameData(Socket socket){
        try {
            ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream());
            return (PlayerData) inputStream.readObject();
        } catch (Exception e) {
            disconnectFromServer();
        } return null;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public PlayerData getPlayerData() {
        return playerData;
    }

    public void setPlayerData(PlayerData playerData) {
        this.playerData = playerData;
    }

    public GameData getGameData() {
        return gameData;
    }

    public void setGameData(GameData gameData) {
        this.gameData = gameData;
    }

    public Socket getSocket() {
        return socket;
    }

    public void setSocket(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        running = true;
        connectToServer();
        while (running){
            while (!playerData.isStarted()) {
                sendPlayerData(socket, playerData);
                readGameData(socket);
            }
            //sendPlayerData(socket, playerData);
            System.out.println("Read...");
            PlayerData data;
            while ((data = readGameData(socket)) != null) {
                playerData = data;
            }
        }
    }
}

这是我在控制器中设置PlayerData的方式:

public void setLoginData(String name, String ip, int port){
        Platform.runLater(() -> {
            client = new ClientTest(port, ip, name);
            System.out.println(client.getPlayerData().getName());
            Thread inputThread = new Thread(client);
            inputThread.start();
            myName.setText(client.getPlayerData().getName());
        });
    }

我希望服务器首先设置两个播放器,然后等待第一个客户端发送数据并为两个播放器设置新数据。

谢谢!

0 个答案:

没有答案