这是一个多线程的服务器客户端程序,目标是让服务器等待来自客户端的三个响应,然后掷三个骰子并相应地检查答案目前我能想到的就是使用数组列表来保存客户端响应和如果列表的长度变为三,则检查答案并发送结果
运行以下代码不会给出任何错误,但是如果客户端输入一个数字,似乎客户端答案没有正确进入数组列表,第一个客户端得到的结果是正确答案是 0,我猜游戏还没有开始但是它说 0 第二个和第三个客户端得到了服务器返回的大量空值,并在我按 Enter 后立即断开连接
所以问题是为什么它总是为客户端 2 和客户端 3 返回 null?
服务器代码:
import java.io.*;
import java.net.*;
import java.util.*;
import java.awt.*;
import javax.swing.*;
public class GameServer extends JFrame {
private JTextArea jta = new JTextArea();
private static int intClient = 0;
public static void main(String[] args) {
new GameServer();
}
public GameServer() {
setLayout(new BorderLayout());
add(new JScrollPane(jta), BorderLayout.CENTER);
setTitle("Game Server");
setSize(500, 300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
try {
ServerSocket serverSocket = new ServerSocket(8000);
jta.append("Server started at " + new Date() + '\n');
jta.setCaretPosition(jta.getDocument().getLength());
while (true) {
try {
Socket socket = serverSocket.accept();
jta.append("Connected with " + socket.getInetAddress().getHostAddress() + " using socket " + socket.getPort() + '\n');
jta.setCaretPosition(jta.getDocument().getLength());
QuoteServerThread qst = new QuoteServerThread(socket, ++intClient);
qst.start();
}
catch (Exception ex) {
System.err.println(ex);
}
}
}
catch (Exception ex) {
System.err.println(ex);
}
}
private class QuoteServerThread extends Thread {
private Socket socket;
private int intClient;
private BufferedReader inputFromClient;
private PrintWriter outputToClient;
QuoteServerThread(Socket parSocket, int parClient) {
socket = parSocket;
intClient = parClient;
}
public void run() {
if (intClient == 1){
jta.append("Waiting for two more players..." + "\n");
} else if (intClient == 2) {
jta.append("Waiting for one more player..." + "\n");
} else if (intClient == 3) {
jta.append("Game Starts!" + "\n");
jta.append("Waiting for guesses..." + "\n");
}
try {
inputFromClient = new BufferedReader(new InputStreamReader(socket.getInputStream()));
outputToClient = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())));
}
catch (Exception ex) {
System.err.println(ex);
}
while (true) {
try {
SimpleDiceGame game = new SimpleDiceGame();
String str = inputFromClient.readLine();
jta.append("Player"+intClient+" Guess:" + str + "\n");
ArrayList<String> clientGuessList = new ArrayList<String>();
clientGuessList.add(intClient-1,str);
if (clientGuessList.size() == 0){
jta.append("waiting for 3 more answers");
} else if (clientGuessList.size() == 1 ){
jta.append("waiting for 2 more answers");
} else if (clientGuessList.size() == 2 ){
jta.append("waiting for 1 more answer");
} else if (clientGuessList.size() == 3){
game.setDices();
jta.append(game.getDices(1) + " " + game.getDices(2) + " " + game.getDices(3) + "\n");
String result = game.checkAnswer(str,intClient);
outputToClient.println("The result is: " + game.getDices(intClient));
outputToClient.println(result);
outputToClient.flush();
jta.setCaretPosition(jta.getDocument().getLength());
clientGuessList.removeAll(clientGuessList);
}
}
catch (Exception ex) {
try {
inputFromClient.close();
outputToClient.close();
socket.close();
jta.append("Disconnected with Player " + intClient + '\n');
jta.setCaretPosition(jta.getDocument().getLength());
break;
}
catch (Exception ex2) {
System.err.println(ex2);
}
System.err.println(ex);
}
}
intClient--;
jta.append("Number of players: " + intClient + "\n");
}
}
}
客户代码:
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GameClient extends JFrame implements Runnable {
private JTextField jtf = new JTextField();
private JTextArea jta = new JTextArea();
private BufferedReader fromServer;
private PrintWriter toServer;
public static void main(String[] args) {
new GameClient();
}
public GameClient() {
JPanel p = new JPanel();
p.setLayout(new BorderLayout());
p.add(new JLabel("Enter quote no."), BorderLayout.WEST);
p.add(jtf, BorderLayout.CENTER);
jtf.setHorizontalAlignment(JTextField.RIGHT);
setLayout(new BorderLayout());
add(p, BorderLayout.NORTH);
add(new JScrollPane(jta), BorderLayout.CENTER);
jtf.addActionListener(new ButtonListener());
setTitle("Quote Client");
setSize(500, 300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
Thread th = new Thread(this);
th.start();
}
public void run() {
try {
Socket socket = new Socket("localhost", 8000);
fromServer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
toServer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())));
while (true) {
try {
String str = fromServer.readLine();
jta.append(str + '\n');
jta.setCaretPosition(jta.getDocument().getLength());
}
catch (Exception ex) {
fromServer.close();
toServer.close();
socket.close();
System.err.println(ex);
}
}
}
catch (Exception ex) {
System.err.println(ex);
}
}
private class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
try {
String str = jtf.getText().trim();
jtf.setSelectionStart(0);
jtf.setSelectionEnd(jtf.getDocument().getLength());
toServer.println(str);
toServer.flush();
jta.append("Your guess is: " + str + "\n");
jta.setCaretPosition(jta.getDocument().getLength());
}
catch (Exception ex) {
System.err.println(ex);
}
}
}
}
简单骰子游戏:
import java.util.Random;
public class SimpleDiceGame {
int[] rolledDices = new int[3];
public String checkAnswer(String stringGuess, int playernum){
int intGuess = 0;
intGuess = Integer.parseInt(stringGuess);
String testResult = null;
if (intGuess == rolledDices[playernum-1]) {
testResult = "Congratulation! You have won!";
} else {
testResult = "Sorry, you missed";
}
return testResult;
}
public void setDices(){
Random r = new Random();
int a = 1+r.nextInt(6);
int b = 1+r.nextInt(6);
int c = 1+r.nextInt(6);
rolledDices[0] = a;
rolledDices[1] = b;
rolledDices[2] = c;
}
public int getDices(int playernum){
return rolledDices[playernum-1];
}
}