簡體   English   中英

Java套接字問題(在tic tac toe游戲中)

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM