我在这里读过类似的帖子,但无法理解什么是解决方案。
我有服务器为每个客户端创建新线程。线程是:
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");
}
}
}
客户是:
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线程运行正常,但dataField的ActionListener会一直运行,直到它记录消息text is sent to server
。
该程序挂起后:
String upperCased = in.readLine();
<{1>} ActionListener
中的。
为什么? 谢谢!
答案 0 :(得分:0)
您需要刷新服务器中的OutputStream
。
out.println(line.toUpperCase());
out.flush();
答案 1 :(得分:0)
您可以尝试使用read()方法从服务器获取响应,如下所示:
int i;
char[] chars = new char[1024];
while ((i = in.read(chars,0,1024)) != -1)
{
messageArea.append(String.valueOf(chars) + "\n");
}
一旦从服务器端发送了数据流,即在您的大写模式中,请关闭OutputStream,完成后添加out.close()
。