简体   繁体   中英

Fail to initialize multiple ObjectInputStream and ObjectOutputStream in Java

I am writing an I/O communication between one server (GameServer) and three clients (GameClient). After the server accepts three clients, it starts a separate thread (HandlePlayer). The HandlePlayer class establishes ObjectInputStream and ObjectOutputStream with three clients.However, at this part, the program stopped (not terminated, but cannot execute any following codes, so I guess the thread may be blocked).

These are the source code of the three classes I mentioned above. I only kept parts relevant to the question

GameServer:

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();
    }

}

HandlePlayer:

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();
        }
        
    }
    

}

GameClient

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();
        }
        
    }
    

Firstly, I tried to run the GameServer in debug mode. It has no problem accepting the three socket connections from three separate clients. Then, after it invokes the HandlePlayer, the program stops at the line fromPlayer1 = new ObjectInputStream(player1.getInputStream()); . It does not move on, but the program is not terminated. enter image description here o

Secondly, I changed all Object IO streams to Data IO streams (DataInputStream and DataOutputStream). Strangely, this time the program works and there is no unexpected stopping. I wonder what makes Object streams different?

Thanks for you reply. This is my first time posting questions on Stack Overflow, please remind me if I don't make myself clear.

I figured out this question on my own. It turns out when both the HandlePlayer and the GameClient are creating the ObjectInputStream, it produces a deadlock as both are waiting for the other's output. After I switched the orders in the GameClient class like this, it worked:

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());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM