[英]Java Server sending messages client after closing
I need some help with this code. 我需要一些关于此代码的帮助。 It's about a Server that suppose to echo the messages from the client back to the client and close after the client types "BYE".
它是关于一个服务器,它假设将客户端的消息回送给客户端,并在客户端键入“BYE”后关闭。 But messages only appear on the client after the server is closed.
但是,服务器关闭后,消息才会出现在客户端上。
I will be grateful if I can get the solution to this problem 如果我能解决这个问题,我将不胜感激
This the code on the Server side: 这是服务器端的代码:
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.");
}
}
And This is the code on the Client side: 这是客户端的代码:
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);
}
}
}
}
You have a Swing threading issue. 你有一个Swing线程问题。 Your
while (true)
is blocking the Swing event thread freezing your program. 你的
while (true)
阻止了Swing事件线程冻结你的程序。 Read on use of background threads, in particular a SwingWorker thread so you can avoid this problem. 阅读后台线程的使用,特别是SwingWorker线程,以便您可以避免此问题。 Start with the Concurrency in Swing Tutorial .
从Swing Tutorial中的Concurrency开始。
You're also starting your reading only after the user types something, and then sending the same String to the server over and over. 只有在用户输入内容后,您才开始阅读,然后一遍又一遍地向服务器发送相同的字符串。
I suggest: 我建议:
out
field via out.println(...)
. out.println(...)
将其发送到out
字段。 out.println("line " + sms);
out.println("line " + sms);
inside of a while (true)
loop, not unless you want to send the same String to the server over and over and over again. while (true)
循环中,除非你想要一遍又一遍地向服务器发送相同的字符串。 Again, this should be in the ActionListener and should be a one shot deal, not called in a loop, but only when the listener is performed. For example, the ActionListener could be as simple as: 例如,ActionListener可以像下面这样简单:
private class TextFieldListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
String sms = jtf.getText().trim();
out.println("line " + sms);
}
}
And in the Client constructor: 并在客户端构造函数中:
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');
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.