admin管理员组

文章数量:1313812

The game starts automatically when 2 clients join the server, then the server waits for client 1 to give an input and afterwards the turn changes. In client 2, the server goes into a waiting state again, but this time, when the client sends the move, the server doesn't seem to get the input.

Server part

private ServerSocket socket;
    private ServerTUI view;
    private ServerLogic serverLogic;
    private int readyCounter;
    private final List<ClientHandler> clients = new ArrayList<ClientHandler>();
    private boolean madeMove = false;
    private int next_client_no;

    public Server() {
        view = new ServerTUI();
        next_client_no = 1;
        readyCounter=0;
    }

    public void run() {
        boolean openNewSocket = true;
        while (openNewSocket) {
            try {
                setup();

                while (true) {
                    Socket sock = socket.accept();
                    ClientHandler handler = new ClientHandler(sock, this);
                    synchronized (clients) {
                        clients.add(handler);
                    }
                    new Thread(handler).start();
                    String name = "Client " + String.format("%02d", next_client_no++);
                    view.showMessage("New client [" + name + "] connected!");
                }
            } catch (Exception e) {
                openNewSocket = false;
            }
        }

    public synchronized void playGame() throws ServerUnavailableException, IOException {
        Player current = null;
        while (!serverLogic.isGameOver(serverLogic.getPlayers().get(serverLogic.getCurrentPlayer()).getRack())) {
            madeMove = false;
            current = serverLogic.getPlayers().get(serverLogic.getCurrentPlayer());
            getServerLogic().setCopyRack(current.getRack());
            getServerLogic().setCopyBoard(getServerLogic().getBoard());
//wait for input
            while (!madeMove) {
                }
            }
            changeTurn();
        }
    }

Server side clienthandler

public class ClientHandler implements Runnable{
    private BufferedReader in;
    private BufferedWriter out;
    private Socket sock;
    private Player player;
    private Server srv;
    private String name;

    public ClientHandler(Socket sock, Server srv){
        try {
            this.sock = sock;
            this.srv = srv;
            in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
            out = new BufferedWriter(new OutputStreamWriter(sock.getOutputStream()));
        } catch (IOException e) {
            shutdown();
        }
    }
    public void run() {
        try {
            String msg;

            while ((msg = in.readLine()) != null) { // it seems to get stuck here
                handleCommand(msg); //sendMessage from here
            }
            shutdown();
        } catch (IOException | ServerUnavailableException e) {
            shutdown();
        }
    }
    public synchronized void sendMessage(String message) throws ServerUnavailableException {
        if (out != null) {
            try {
                out.write(message);
                out.newLine();
                out.flush();
            } catch (IOException e) {
                throw new ServerUnavailableException("Could not send message to client: " + e.getMessage());
            }
        }
    }

Client side

public class Client implements Runnable {
    @Override
    public void run() {
        try {
            String command;
            while (serverSock.isConnected()) {
                command = in.readLine();
                processCommand(command);
            }
        } catch (IOException | ProtocolException e) {
            throw new RuntimeException(e);
        }
    }
    public void startClient() {
        startConnection();
    }

    public void startConnection() {
        // To be implemented
        boolean connected = false;
        while (!connected) {
            try {
                createConnection();
                name = view.getString("Please enter name");
                if (Protocol.isValidName(name)) {
                    handleHello();
                } else {
                    System.out.println("Please enter valid name");
                    break;
                }
                connected = true;
                Thread listenerThread = new Thread(this);
                listenerThread.start();
            } catch (ExitProgram e) {
                view.showMessage("Exiting the program...");
                break;
            } catch (ServerUnavailableException e) {
                view.showMessage("Connection failed: " + e.getMessage());
                if (!view.getBoolean("Do you want to try again?")) {
                    break;
                }
            } catch (ProtocolException e) {
                throw new RuntimeException(e);
            }
        }
    }

    public synchronized void sendMessage(String msg)
            throws ServerUnavailableException {
        if (out != null) {
            try {
                out.write(msg);
                out.newLine();
                out.flush();
            } catch (IOException e) {
                view.showMessage(e.getMessage());
                throw new ServerUnavailableException("Could not write " + msg + "to server.");
            }
        } else {
            throw new ServerUnavailableException("Could not write " + msg
                    + "to server.");
        }
    }

Tried debugging every step, but with threads and 2 different clients sometimes it gave weird behavior, tried having one separate class for all the communication (sendMessage), tried a lot of different approaches the past few days leading to the same spot.

本文标签: