简体   繁体   English

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

[英]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: 我建议:

  • Use a background thread or SwingWorker to read from the server in the client. 使用后台线程或SwingWorker从客户端中的服务器读取。 This should be set up in the client's constructor, not in the ActionListener. 这应该在客户端的构造函数中设置,而不是在ActionListener中。
  • Make sure that you append to the client's text area on the Swing event thread or EDT. 确保在Swing事件线程或EDT 附加到客户端的文本区域。 A SwingWorker will help you do this via the publish/process method pair. SwingWorker将通过发布/处理方法对帮助您完成此操作。
  • The ActionListener should be much simpler. ActionListener应该更简单。 All it should do is get the JTextField's text and send it to your out field via out.println(...) . 它应该做的就是获取JTextField的文本并通过out.println(...)将其发送到out字段。
  • Again, do not have 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. 同样,这应该在ActionListener中,并且应该是一次性处理,不是在循环中调用,而是仅在执行侦听器时。

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.

相关问题 将消息从C服务器发送到Java客户端 - Sending messages from C server to Java client 关闭后Java客户端/服务器资源泄漏 - Java Client/Server resource leak after closing 客户端重新连接到服务器后,从服务器向客户端发送Java消息 - Java-messages to client from server after client reconnects to server 使用Java Websockets客户端向服务器发送多条消息? - Sending multiple messages to a server using Java Websockets Client side? 套接字阻止在 Java 服务器和 Python 客户端之间发送消息 - Socket blocks sending messages between a Java server and Python client Java客户端/服务器聊天室将消息作为对象发送 - Java Client/Server chat room sending messages as objects Java Soket线程服务器将消息发送回特定客户端 - Java Soket Threaded Server sending messages back to specific client 使用DataOutputStream向Server Socket写消息到Client Socket的消息仅在关闭Client Socket后才发送,为什么? - Writing messages to client socket using DataOutputStream to Server Socket only sent after closing the Client Socket why? Java NIO服务器/客户端聊天应用程序-仅通过关闭套接字来发送数据 - Java NIO Server/Client Chat App - sending data only by closing the socket TCP / IP客户端向服务器发送多个消息 - TCP/IP Client sending multiple messages to Server
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM