我已經使用套接字(無線程)在Java中構建了一個雙人井字遊戲遊戲。我有它的工作,除了在遊戲結束時終止客戶。基本上,我已經設置好了,一旦遊戲結束(服務器識別出勝利或平局),服務器就會向兩個客戶端發送消息。如果客戶端讀取了特定的消息,那麼他們將「脫離」它們的do-while循環並關閉套接字連接。Java插座問題(在井字棋遊戲中)
問題是,無論何時一個客戶端關閉,另一個會「崩潰」 - 它會終止,但不會成功(它會引發錯誤信息)。考慮打開三個終端 - 兩個客戶端和一個服務器。如果我在一個客戶端上點擊「Ctrl-C」(退出),另一個客戶端將停止。客戶應該完全分開,我不明白爲什麼會發生這種情況。
我打算髮布我的服務器代碼和我的客戶端代碼(刪除了Tic Tac Toe邏輯後) - 任何人都可以看到我在做什麼錯了嗎?謝謝!
更新:我添加了打印語句到try-catch,但是這不是停止問題。我收到的錯誤是這樣的:
Exception in thread "main" java.lang.ClassCastException: java.lang.String
at Requester.run(Requester.java:32)
at Requester.main(Requester.java:142)
我改變了下面的代碼,包括所有的井字遊戲邏輯。 Requester.java:32是
currentPlayer = (Integer) in.readObject();
...在第一個do-try語句後面。任何人都可以看到發生了什麼?
服務器
import java.io.*;
import java.net.*;
public class Provider {
TBoard board = new TBoard();
ServerSocket providerSocket;
Socket connection1 = null, connection2 = null;
ObjectOutputStream out, out2;
ObjectInputStream in, in2;
String message;
Boolean done = false;
int row;
int col;
Provider() {
}
void run() {
try {
providerSocket = new ServerSocket(20092);
System.out.println("Waiting for connection...");
connection1 = providerSocket.accept();
System.out.println("Connection received from Player 1 "
+ connection1.getInetAddress().getHostName());
connection2 = providerSocket.accept();
System.out.println("Connection received from Player 2 "
+ connection2.getInetAddress().getHostName());
out = new ObjectOutputStream(connection1.getOutputStream());
out2 = new ObjectOutputStream(connection2.getOutputStream());
in = new ObjectInputStream(connection1.getInputStream());
in2 = new ObjectInputStream(connection2.getInputStream());
do {
if (board.get_player() == 1) {
out.writeObject(board.get_player());
out.flush();
out.writeObject(board.print_board());
out.flush();
}
else {
out2.writeObject(board.get_player());
out2.flush();
out2.writeObject(board.print_board());
out2.flush();
}
sendMessage(board.get_player(),
"Please enter a row, press Enter, then enter a column: ");
if (board.get_player() == 1) {
int[][] c_array = (int[][]) in.readObject();
board.set_array(c_array);
}
else {
int[][] c_array = (int[][]) in2.readObject();
board.set_array(c_array);
}
if (board.get_player() == 1) {
board.set_player(2);
}
else {
board.set_player(1);
}
if (board.winner() != 0) {
System.out.print("The winner is...");
if (board.get_player() == 1) {
System.out.println("Player 2!");
}
else {
System.out.println("Player 1!");
}
out.writeObject("bye");
out.flush();
out2.writeObject("bye");
out2.flush();
done = true;
}
else {
if(board.get_player() == 2){
out.writeObject("nothing");
out.flush();
}
else{
out2.writeObject("nothing");
out2.flush();
}
}
} while (done != true);
}
catch (IOException ioException) {
ioException.printStackTrace();
}
catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally {
try {
in.close();
out.close();
in2.close();
out2.close();
providerSocket.close();
}
catch (IOException ioException) {
ioException.printStackTrace();
}
}
}
void sendMessage(int player, String msg) {
try {
if (player == 1) {
out.writeObject(msg);
out.flush();
}
else {
out2.writeObject(msg);
out2.flush();
}
}
catch (IOException ioException) {
ioException.printStackTrace();
}
}
public static void main(String args[]) {
Provider server = new Provider();
while (true) {
server.run();
}
}
}
客戶:
import java.io.*;
import java.net.*;
import java.util.Scanner;
public class Requester {
TBoard board = new TBoard();
Socket requestSocket;
ObjectOutputStream out;
ObjectInputStream in;
String message;
String endmessage = "";
int row, col, currentPlayer;
Scanner scan = new Scanner(System.in);
Requester() {
}
void run() {
try {
requestSocket = new Socket("server2.xx.xxxx.xxx", 20092);
System.out.println("Connected to localhost in port 20092");
out = new ObjectOutputStream(requestSocket.getOutputStream());
in = new ObjectInputStream(requestSocket.getInputStream());
do {
try {
currentPlayer = (Integer) in.readObject();
board.set_player(currentPlayer);
int[][] b_array = (int[][]) in.readObject();
board.set_array(b_array);
for (int i = 0; i < 3; i++) {
System.out.println("");
for (int j = 0; j < 3; j++) {
if (b_array[i][j] == 1) {
System.out.print(" X");
}
else if (b_array[i][j] == 2) {
System.out.print(" O");
}
else {
System.out.print(" -");
}
}
}
System.out.println();
message = (String) in.readObject();
System.out.print(message);
row = scan.nextInt();
while (row < 0 || row > 2) {
System.out
.print("Row is invalid, please choose again (0-2): ");
row = scan.nextInt();
}
col = scan.nextInt();
while (col < 0 || col > 2) {
System.out
.print("Column is invalid, please choose again (0-2): ");
col = scan.nextInt();
}
while (!board.make_move(row, col)) {
System.out
.print("The move is not valid. Please choose another row (0-2): ");
row = scan.nextInt();
while (row < 0 || row > 2) {
System.out
.print("Row is invalid, please choose again (0-2): ");
row = scan.nextInt();
}
System.out.print("Please choose a column (0-2): ");
col = scan.nextInt();
while (col < 0 || col > 2) {
System.out
.print("Column is invalid, please choose again (0-2): ");
row = scan.nextInt();
}
}
for (int i = 0; i < 3; i++) {
System.out.println("");
for (int j = 0; j < 3; j++) {
if (b_array[i][j] == 1) {
System.out.print(" X");
}
else if (b_array[i][j] == 2) {
System.out.print(" O");
}
else {
System.out.print(" -");
}
}
}
System.out.println();
out.writeObject(board.print_board());
out.flush();
endmessage = (String) in.readObject();
}
catch (ClassNotFoundException classNot) {
System.err.println("data received in unknown format");
}
} while (!endmessage.equals("bye"));
}
catch (UnknownHostException unknownHost) {
System.err.println("You are trying to connect to an unknown host!");
}
catch (IOException ioException) {
ioException.printStackTrace();
}
finally {
try {
in.close();
out.close();
requestSocket.close();
}
catch (IOException ioException) {
ioException.printStackTrace();
}
}
}
void sendMessage(int msg) {
try {
out.writeObject(msg);
out.flush();
}
catch (IOException ioException) {
ioException.printStackTrace();
}
}
public static void main(String args[]) {
Requester client = new Requester();
client.run();
}
}
...任何幫助都很棒,我一直堅持這一天。謝謝!
什麼是引發的錯誤信息? – 2009-09-30 12:52:50
拋出的錯誤消息是一個ClassCastException - 基本上,如果Client1進行移動,服務器將檢查一個勝利,並且在客戶端執行的結束將檢查「已完成」消息。如果它收到該消息,則Client1將終止,並且Client2將因上述錯誤而崩潰 - 因爲它位於do-while循環的頂部,正在等待來自服務器的第一條指令。 – littleK 2009-09-30 12:57:52
看起來好像你已經成功註釋掉了實際拋出ClassCastException(/ Tic Tac Toe邏輯)的代碼。無法看到您通過網絡發送的內容以及收到的數據的處理方式。 – jarnbjo 2009-09-30 13:05:38