我需要一些关于此代码的帮助。它是关于一个服务器,它假设将客户端的消息回送给客户端,并在客户端键入“BYE”后关闭。但是,只有在服务器关闭后才会在客户端上显示消息。
如果我能解决这个问题,我将不胜感激
这是服务器端的代码:
import java.io.*;
import java.net.*;
import java.util.*;
import java.awt.*;
import javax.swing.*;
public class EchoServer extends JFrame{
private JTextArea jta = new JTextArea();
public static void main(String[] args) {
new EchoServer();
}
public EchoServer(){
setLayout(new BorderLayout());
add(new JScrollPane(jta), BorderLayout.CENTER);
setTitle("Server");
setSize(500, 300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
try {
//Creating Server socket
ServerSocket s = new ServerSocket(5000);
//Display messge to show the server has bean running
jta.append("Echo Server Started" + '\n');
/*This is a blocking Statement
*The program comes to a stand still until the ACCEPT method returns
*/
Socket incoming = s.accept();
jta.append("Connected to: " + incoming.getInetAddress() +
" at port: " + incoming.getLocalPort() + '\n' + '\n');
BufferedReader in
= new BufferedReader(new InputStreamReader(incoming.getInputStream()));
PrintWriter out
= new PrintWriter(incoming.getOutputStream(), true);
//Display welcome message
out.println("Hi my SERVER. Enter BYE to exit.");
for (;;) {
String str = in.readLine();
if (str == null) {
break;
} else {
//Display information from Client
out.println("Echo: " + str);
jta.append("Received: " + str + '\n');
if (str.trim().equals("BYE"))
break;
}
}
//incoming.close();
} catch (Exception e) {
jta.append("Error: " + e);
}
jta.append("EchoServer stopped.");
}
}
这是客户端的代码:
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Client extends JFrame {
private JTextField jtf = new JTextField();
private JTextArea jta = new JTextArea();
private BufferedReader in;
private PrintWriter out;
public static void main(String[] args){
new Client();
}
public Client(){
JPanel p = new JPanel();
p.setLayout(new BorderLayout());
p.add(new JLabel("Enter Text:"), BorderLayout.WEST);
p.add(jtf, BorderLayout.CENTER);
jtf.setHorizontalAlignment(JTextField.RIGHT);
setLayout(new BorderLayout());
add(p, BorderLayout.NORTH);
add(new JScrollPane(jta), BorderLayout.CENTER);
jtf.addActionListener(new TextFieldListener());
setTitle("Client");
setSize(500, 300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
try {
//creating a socket
Socket socket= new Socket("localhost", 5000);
in = new
BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new
PrintWriter(socket.getOutputStream(), true);
}
catch(IOException ex){
jta.append(ex.toString() + '\n');
}
}
private class TextFieldListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e){
try{
while (true){
String str= in.readLine();
if (str == null) {
//break out of loop
break;
} else {
//Display input from server
jta.append(str + "\n");
/*enable user to in the text that
will be sent ot the server
*/
String sms = jtf.getText().trim();
if ("BYE".equals(sms)){
/*if the user types "BYE" send it to the server
and break out of the loop
*/
out.println("BYE");
break;
}
//send messages to the server
out.println("line " + sms);
}
}
}
catch (IOException ex) {
System.err.println(ex);
}
}
}
}
答案 0 :(得分:4)
您有Swing线程问题。您的while (true)
阻止Swing事件线程冻结您的程序。阅读后台线程的使用,特别是SwingWorker线程,以便您可以避免此问题。从Concurrency in Swing Tutorial开始。
只有在用户输入内容后,您才开始阅读,然后一遍又一遍地向服务器发送相同的字符串。
我建议:
out
将其发送到out.println(...)
字段。out.println("line " + sms);
循环中没有while (true)
,除非您想要一遍又一遍地向服务器发送相同的字符串。同样,这应该在ActionListener中并且应该是一次性交易,不是在循环中调用,而是仅在执行监听器时。例如,ActionListener可以简单如下:
private class TextFieldListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
String sms = jtf.getText().trim();
out.println("line " + sms);
}
}
在Client构造函数中:
try {
Socket socket = new Socket("localhost", 5000);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// !!
new Thread(new Runnable() {
@Override
public void run() {
try {
while (true) {
final String str = in.readLine();
if (str == null) {
break;
} else {
// ***** call Swing code on the Swing event thread:
SwingUtilities.invokeLater(new Runnable() {
public void run() {
jta.append(str + "\n");
}
});
// String sms = jtf.getText().trim();
// if ("BYE".equals(sms)) {
// out.println("BYE");
// break;
// }
// ***** don't call this here!!! *****
// out.println("line " + sms);
}
}
} catch (IOException ex) {
System.err.println(ex);
}
}
}).start();
out = new PrintWriter(socket.getOutputStream(), true);
} catch (IOException ex) {
jta.append(ex.toString() + '\n');
}