gpt4 book ai didi

Java Server 关闭后向客户端发送消息

转载 作者:可可西里 更新时间:2023-11-01 02:45:27 26 4
gpt4 key购买 nike

我需要一些关于此代码的帮助。它是关于一个服务器,它假设将来自客户端的消息回显给客户端并在客户端键入“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);
}
}
}
}

最佳答案

您遇到了 Swing 线程问题。您的 while (true) 正在阻止 Swing 事件线程卡住您的程序。阅读后台线程的使用,特别是 SwingWorker 线程,这样您就可以避免这个问题。从 Concurrency in Swing Tutorial 开始.

您也只是在用户输入内容后才开始阅读,然后一遍又一遍地向服务器发送相同的字符串。

我建议:

  • 在客户端使用后台线程或 SwingWorker 从服务器读取数据。这应该在客户端的构造函数中设置,而不是在 ActionListener 中。
  • 确保您在 Swing 事件线程或 EDT 上附加到客户端的文本区域。 SwingWorker 将通过发布/处理方法对帮助您执行此操作。
  • ActionListener 应该简单得多。它应该做的就是获取 JTextField 的文本并通过 out.println(...) 将其发送到您的 out 字段。
  • 同样,不要在 while (true) 循环中使用 out.println("line "+ sms);,除非你想发送相同的内容一遍又一遍地向服务器发送字符串。同样,这应该在 ActionListener 中并且应该是一次性交易,而不是在循环中调用,而仅在执行监听器时调用。

例如,ActionListener 可以像这样简单:

private class TextFieldListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
String sms = jtf.getText().trim();
out.println("line " + sms);
}
}

在客户端构造函数中:

  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');
}

关于Java Server 关闭后向客户端发送消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19552884/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com