Java socket/JavaFX - 发送 mssgs 会使客户端停止工作



我正在尝试使用java套接字做检查器。但是,当我运行客户端时,它会卡在循环中并停止响应。

到目前为止,我的应用程序具有绘制棋盘,移动跳棋以及在服务器和客户端之间创建连接的方法。 连接已正确创建。

问题出在负责处理服务器消息的 play(( 上。

请帮助我修改 play(( 以使其正常工作。


客户端应用


public class CheckersApp extends Application {
public static final int TILE_SIZE = 100;
public static final int WIDTH = 8;
public static final int HEIGHT = 8;
private Tile[][] board = new Tile[WIDTH][HEIGHT];
private Group tileGroup = new Group();
private Group pieceGroup = new Group();
private Label text = new Label();
private static int PORT = 8901;
private Socket socket;
private BufferedReader in;
private PrintWriter out;
// method to draw a board with checkers
private Parent createContent() {
...
}
// method to check if moving checkers is possbile
private MoveResult tryMove(Piece piece, int newX, int newY) {
...
}
@Override
public void start(Stage primaryStage) throws Exception {
Scene scene = new Scene(createContent());
primaryStage.setTitle("CheckersApp");
primaryStage.setScene(scene);
primaryStage.show();
// Setup networking
socket = new Socket("LAP00132", PORT);
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
play();
}
// method to move checkers
private Piece makePiece(PieceType type, int x, int y) {
...
}
// method to get responses from Server
public void play() throws Exception {
String response;
try {
response = in.readLine();
if (response.startsWith("WELCOME")) {
// char mark = response.charAt(8);
}
while (true) {
response = in.readLine();
if (response.startsWith("VALID_MOVE")) {
text.setText("Valid move, please wait");
} else if (response.startsWith("OPPONENT_MOVED")) {
text.setText("Opponent moved, your turn");
} else if (response.startsWith("VICTORY")) {
text.setText("You win");
break;
} else if (response.startsWith("DEFEAT")) {
text.setText("You lose");
break;
} else if (response.startsWith("TIE")) {
text.setText("You tied");
break;
} else if (response.startsWith("MESSAGE")) {
text.setText(response.substring(8));
}
}
out.println("QUIT");
}
finally {
socket.close();
}
}
public static void main(String[] args) {
launch(args);}

服务器应用程序


public class Server {
/**
* Runs the application. Pairs up clients that connect.
*/
public static void main(String[] args) throws Exception {
ServerSocket listener = new ServerSocket(8901);
System.out.println("Server is Running");
try {
while (true) {
Game game = new Game();
Game.Player playerX = game.new Player(listener.accept(), 'X');
System.out.println("Połączony X");
Game.Player playerO = game.new Player(listener.accept(), 'O');
System.out.println("Połączony O");
playerX.setOpponent(playerO);
playerO.setOpponent(playerX);
game.currentPlayer = playerX;
playerX.start();
playerO.start();
}
} finally {
listener.close();}}}


class Game {
public static final int WIDTH = 8;
public static final int HEIGHT = 8;
//private Tile[][] board = new Tile[WIDTH][HEIGHT];
Player currentPlayer;
/**
* Called by the player threads when a player tries to make a
* move.  This method checks to see if the move is legal: that
* is, the player requesting the move must be the current player
*/
public synchronized boolean legalMove(Player player) {
if (player == currentPlayer) {
currentPlayer = currentPlayer.opponent;
currentPlayer.otherPlayerMoved();
return true;
}
return false;
}

class Player extends Thread {
char mark;
Player opponent;
Socket socket;
BufferedReader input;
PrintWriter output;
/**
* Constructs a handler thread for a given socket and mark
* initializes the stream fields, displays the first two
* welcoming messages.
*/
public Player(Socket socket, char mark) {
this.socket = socket;
this.mark = mark;
try {
input = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
output = new PrintWriter(socket.getOutputStream(), true);
output.println("WELCOME " + mark);
System.out.println("Welcome ");
output.println("MESSAGE Waiting for opponent to connect");
} catch (IOException e) {
System.out.println("Player died: " + e);
}
}
/**
* Accepts notification of who the opponent is.
*/
public void setOpponent(Player opponent) {
this.opponent = opponent;
}
/**
* Handles the otherPlayerMoved message.
*/
public void otherPlayerMoved() {
output.println("OPPONENT_MOVED ");
System.out.println("OPPONENT_MOVED");
}

/**
* The run method of this thread.
*/
public void run() {
try {
// The thread is only started after everyone connects.
output.println("MESSAGE All players connected");
// Tell the first player that it is her turn.
if (mark == 'X') {
output.println("MESSAGE Your move");
}
// Repeatedly get commands from the client and process them.
while (true) {
String command = input.readLine();
if (command.startsWith("MOVE")) {
if (legalMove(this)) {
output.println("VALID_MOVE");
System.out.println("VALID MOVE");
} else {
output.println("MESSAGE ?");
}
} else if (command.startsWith("QUIT")) {
return;
}
}
} catch (IOException e) {
System.out.println("Player died: " + e);
} finally {
try {socket.close();} catch (IOException e) {}
}
}
}}

您的while(true)循环只是等待一行。它阻止对 UI 执行任何操作的能力。

生成一个单独的线程来处理服务器通信。显然,您需要了解模型和UI数据的多线程和多线程访问的危险。

最新更新