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!
You need to flush the OutputStream
in the server.
out.println(line.toUpperCase());
out.flush();