【问题标题】:Fail to initialize multiple ObjectInputStream and ObjectOutputStream in Java无法在 Java 中初始化多个 ObjectInputStream 和 ObjectOutputStream
【发布时间】:2023-01-25 17:03:55
【问题描述】:

我正在编写一个服务器 (GameServer) 和三个客户端 (GameClient) 之间的 I/O 通信。服务端接受三个客户端后,启动一个单独的线程(HandlePlayer)。 HandlePlayer类建立了三个clients的ObjectInputStream和ObjectOutputStream。但是在这部分,程序停止了(没有终止,但是不能执行后面的任何代码,所以我猜测线程可能被阻塞了)。

这些就是我上面提到的三个类的源代码。我只保留了与问题相关的部分

游戏服务器:

public class GameServer implements Runnable, ShareData {
    
    
    public void run() {
        try {
            ServerSocket serverSocket = new ServerSocket(PORT);
            System.out.println("server start at port " + PORT);
            
            // wait for players to connect
            while (true) {
                Socket player1 = serverSocket.accept();
                System.out.println("player 1: " + player1.getInetAddress().getHostAddress());

                Socket player2 = serverSocket.accept(); // connect to player 2
                System.out.println("player 2: " + player2.getInetAddress().getHostAddress());
                
                Socket player3 = serverSocket.accept(); // connect to player 3
                System.out.println("player 3: " + player3.getInetAddress().getHostAddress());
                
                
                // start the game
                new Thread(new HandlePlayer(player1, player2, player3)).start();
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        Thread server = new Thread(new GameServer());
        server.start();
    }

}

手柄播放器:

public class HandlePlayer implements Runnable, ShareData {
    
    // three players
    private Socket player1;
    private Socket player2;
    private Socket player3;
    
    // communication with players
    ObjectInputStream fromPlayer1;
    ObjectOutputStream toPlayer1;
    ObjectInputStream fromPlayer2;
    ObjectOutputStream toPlayer2;
    ObjectInputStream fromPlayer3;
    ObjectOutputStream toPlayer3;

    
    public HandlePlayer(Socket player1, Socket player2, Socket player3) {
        this.player1 = player1;
        this.player2 = player2;
        this.player3 = player3;
    }
    
    
    // start the game
    public void run() {
        try {
            // initialize communication connections
            fromPlayer1 = new ObjectInputStream(player1.getInputStream());
            toPlayer1 = new ObjectOutputStream(player1.getOutputStream());
            fromPlayer2 = new ObjectInputStream(player2.getInputStream());
            toPlayer2 = new ObjectOutputStream(player2.getOutputStream());
            fromPlayer3 = new ObjectInputStream(player3.getInputStream());
            toPlayer3 = new ObjectOutputStream(player3.getOutputStream());
            
            
            // receive robot selections
            char player1Robot = fromPlayer1.readChar();
            char player2Robot = fromPlayer2.readChar();
            char player3Robot = fromPlayer3.readChar();
            
            // the game loop
            
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
    }
    

}

游戏客户端

public class GameClient implements Runnable, ShareData {
    
    private ObjectInputStream fromServer;
    private ObjectOutputStream toServer;
    private Scanner input = new Scanner(System.in);
    private String host = "localhost";
    
    // connect to server
    private void connectToServer() {
        try {
            Socket socket = new Socket(host, PORT);
            fromServer = new ObjectInputStream(socket.getInputStream());
            toServer = new ObjectOutputStream(socket.getOutputStream());
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    
    
    public void run() {
        try {
            connectToServer();
        } catch (Exception e) {
            e.printStackTrace();
        }
        
    }
    

首先,我尝试在调试模式下运行 GameServer。接受来自三个独立客户端的三个套接字连接没有问题。然后,在调用 HandlePlayer 之后,程序停在该行fromPlayer1 = new ObjectInputStream(player1.getInputStream());.它不会继续前进,但程序不会终止。 enter image description here o

其次,我将所有对象 IO 流更改为数据 IO 流(DataInputStream 和 DataOutputStream)。奇怪的是,这次程序运行正常并且没有意外停止。我想知道是什么让对象流与众不同?

谢谢你的回复。这是我第一次在Stack Overflow上发帖提问,有没有说清楚的请多多指教。

【问题讨论】:

  • 有两件事立刻让我印象深刻:一种。如果许多客户端尝试连接,您很容易遇到麻烦,accept 阻塞了您的主线程,更重要的是,b.你应该使用线程每个客户,不仅仅是每个客户三元组

标签: java networking io objectinputstream objectoutputstream


【解决方案1】:

我自己想出了这个问题。事实证明,当 HandlePlayer 和 GameClient 都在创建 ObjectInputStream 时,会产生死锁,因为两者都在等待对方的输出。在我像这样切换 GameClient 类中的订单后,它起作用了:

toPlayer1 = new ObjectOutputStream(player1.getOutputStream());
toPlayer2 = new ObjectOutputStream(player2.getOutputStream());
toPlayer3 = new ObjectOutputStream(player3.getOutputStream());
fromPlayer1 = new ObjectInputStream(player1.getInputStream());
fromPlayer2 = new ObjectInputStream(player2.getInputStream());
fromPlayer3 = new ObjectInputStream(player3.getInputStream());

【讨论】:

    猜你喜欢
    • 2015-01-05
    • 2012-05-29
    • 2018-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-07
    相关资源
    最近更新 更多