[英]Problem with Java Sockets (in tic tac toe game)
我用Java建立了一個雙人tic tac toe游戲,使用套接字(無線程)。 我有它工作,除了在游戲結束時終止客戶端。 基本上,我已將其設置為一旦游戲結束(服務器識別出勝利或平局),服務器將向兩個客戶端發送消息。 如果客戶端讀取該特定消息,那么它們將“突破”其do-while循環並關閉套接字連接。
問題是,每當一個客戶端關閉,另一個客戶端將“崩潰” - 它將終止,但不會成功(它將拋出錯誤消息)。 考慮打開三個終端 - 兩個客戶端和一個服務器。 如果我在一個客戶端終端上按“Ctrl-C”(退出),則另一個客戶端將停止。 客戶應該完全分開,我不明白為什么會這樣。
我將發布我的服務器代碼和我的客戶端代碼(在刪除了Tic Tac Toe邏輯之后) - 任何人都可以看到我做錯了嗎? 謝謝!
更新:我在try-catch中添加了print語句,但這並沒有阻止問題。 我收到的錯誤是這樣的:
Exception in thread "main" java.lang.ClassCastException: java.lang.String
at Requester.run(Requester.java:32)
at Requester.main(Requester.java:142)
我更改了下面的代碼以包含所有Tic Tac Toe邏輯。 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();
}
}
......任何幫助都會很棒,我已經堅持了好幾天。 謝謝!
當兩個用戶中的一個關閉程序時。 連接“中斷”。 然后socket-class拋出一個IOException,你捕獲:
...
} catch (IOException ioException) {
ioException.printStackTrace();
}
...
但在捕捉之后,你什么都不做。 您必須添加一些消息並說連接已斷開。 我認為你的程序不會崩潰,只是停止因為他捕獲了exeption而不是關閉finnaly
的流。
希望這可以幫助。
在您的Server類中,在catch(IOException ioException){}中
你可以捕獲哪個ObjectInputStream拋出了異常(因為關閉客戶端在服務器端生成IOException)然后向另一個客戶端發送“win,因為你的對手已斷開連接”
我認為你的“同步”被卡住了。 嘗試打印出您閱讀的變量。 並打印您認為您將閱讀的內容。
例:
// Set Current Player
System.out.println("Reading current player");
Object inputCP = in.readObject();
System.out.println(inputCP.getClass().getName() + " " + inputCP);
board.set_player((int) (Integer) inputCP);
寫入相同,並比較輸出。 因此,您可以看到發送和接收數據的同步化有什么問題。
注意:如果將對象寫入ObjectOutputStream,則會自動刷新。
在黑暗中刺傷,但是捕獲IOException並不能解決classCastException的問題,這是你說的錯誤:
Exception in thread "main" java.lang.ClassCastException: java.lang.String
at Requester.run(Requester.java:32)
at Requester.main(Requester.java:142)
你說請求者的第32行是:
currentPlayer = (Integer) in.readObject();
您試圖將in.readObject()置於Integer中,但它實際上是一個String,因此是異常。
但是,不要只是捕獲異常,鍛煉為什么你得到一個字符串而不是整數。
我的猜測是你發布的服務器代碼和void sendMessage(int player,String msg)方法。 它看起來像是發送一個String消息,但期望另一端有一個整數。 你可能想稍微整理一下
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.