2

I have two methods in server and in client:

Server:

@Override
    public void start(Stage primaryStage) throws Exception {
        socket = new Socket("localhost", 9998);
        System.out.println("connected");
        input = new ObjectInputStream(socket.getInputStream());
        System.out.println("1");
        output = new ObjectOutputStream(socket.getOutputStream());

        output.writeObject(new Message(CONFIG, "ping"));

        FXMLLoader loader = new FXMLLoader(this.getClass().getResource("/window/fxmls/window.fxml"));
        loader.setController(this);
        AnchorPane anchorPane = loader.load();
        Scene scene = new Scene(anchorPane);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

Client:

@Override
    public void run() {
        try {
            serverSocket = new ServerSocket(9998);
            while (true) {
                Socket socket = serverSocket.accept();
                System.out.println("connected");
                input = new ObjectInputStream(socket.getInputStream());
                System.out.println(1);
                output = new ObjectOutputStream(socket.getOutputStream());
                Message message = (Message) input.readObject();
                if (message.getHeader() == CONFIG && message.getMessage().equals("ping")) {
                    System.out.println(message.getMessage());
                }
            }
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

When client is start running, sends checking message "ping" using ObjecInputStream, but code in above methods is stopping on System.out.println(1); I don't know why. Before in similar code all was running. What I did bad? input = new ObjectInputStream(socket.getInputStream()); is waiting for something what I haven't done?

1 Answers1

2

You essentially have a deadlock here. If you start the server first, it will start listening for connections on port 9998. When you then start the client, it makes a connection to the server. The server accepts the connection, and tries to create an ObjectInputStream. The ObjectInputStream constructor (and the server thread) will block until it can read a stream header from the client (which the client hasn't sent yet). So the server doesn't get to the point where it creates an ObjectOutputStream (which would cause data to be sent to the client).

Meanwhile the client is attempting to create an ObjectInputStream and will block because the server hasn't yet sent any data. The result is two threads blocked in the ObjectInputStream constructor.

The solution is quite simple - in the server, create the ObjectOutputStream first, then create the ObjectInputStream:

socket = new Socket("localhost", 9998);
output = new ObjectOutputStream(socket.getOutputStream());
input = new ObjectInputStream(socket.getInputStream());
Richard Fearn
  • 25,073
  • 7
  • 56
  • 55
  • I have done how you sayed, but `output.writeObject(new Message(CONFIG, "ping"));` is doing error: `Exception in thread "main" java.lang.reflect.InvocationTargetException`. –  Jan 08 '19 at 20:10
  • You should probably create a new question for that. – Richard Fearn Jan 08 '19 at 22:19