Search code examples
javasocketsserversocket

Why comp hangs up when reading and writing with sockets in java


I have read similar posts here but can't understand what is solution.

I have server that creates new thread for each client. Thread is :

private static class Capitalizer extends Thread {
        private Socket socket;
        private int clientNumber;

        public Capitalizer(Socket socket, int clientNumber) {
            this.socket = socket;
            this.clientNumber = clientNumber;
            log("New connection with client " + clientNumber + " at " + socket);
        }

        private void log(String message) {
            System.out.println(message);
        }

        @Override
        public void run() {
            try {
                BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                PrintWriter out = new PrintWriter(socket.getOutputStream(), true);

                out.println("Hello, you are a client " + clientNumber);
                out.println("Enter a line with only a period to exit");

                while (true) {
                    String line = in.readLine();
                    if (line == null || line.equals("."))
                        break;
                    out.println(line.toUpperCase());
                    System.out.println("Server capitalized " + line);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                log("Connection with client " + clientNumber + " is closed");
            }
        }
    }

And client is :

public class CapitalizeClient {
    private BufferedReader in;
    private PrintWriter out;
    private JFrame mainWindow = new JFrame("Capitalize Client");
    private JTextField dataField = new JTextField(40);
    private JTextArea messageArea = new JTextArea(8, 60);

    public CapitalizeClient() {

        messageArea.setEditable(false);
        mainWindow.getContentPane().add(dataField, BorderLayout.NORTH);
        mainWindow.getContentPane().add(new JScrollPane(messageArea));

        dataField.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                String text = dataField.getText();
                out.println(text);
                System.out.println("text is sent to server");
                try {
                    String upperCased = in.readLine();
                    if (upperCased == null || upperCased.equals("."))
                        System.exit(0);
                    System.out.println("ActionListener " + text);
                    messageArea.append(upperCased + "\n");
                    dataField.selectAll();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        });
    }

    private void connectToServer() throws UnknownHostException, IOException {
        String serverAddress = JOptionPane.showInputDialog(mainWindow, "Enter word 'localhost'",
                "Welcome to the capitalization program", JOptionPane.QUESTION_MESSAGE);

        Socket socket = new Socket(serverAddress, CapitalizeServer.port);

        in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        out = new PrintWriter(socket.getOutputStream(), true);

        String line;
        while ((line = in.readLine()) != null) {
            messageArea.append(line + "\n");
        }

    }

    public static void main(String[] args) throws UnknownHostException, IOException {
        CapitalizeClient client = new CapitalizeClient();
        client.mainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        client.mainWindow.pack();
        client.mainWindow.setVisible(true);
        client.connectToServer();
    }
}

Capitalizer thread runs ok but ActionListener of dataField runs until it logs message text is sent to server.

After that program hangs up on line:

String upperCased = in.readLine();

in ActionListener of dataField.

Why is it? Thank you!


Solution

  • You need to flush the OutputStream in the server.

    out.println(line.toUpperCase());
    out.flush();