2013-10-23 41 views
1

我需要一些关于此代码的帮助。这是关于一个服务器,假设将消息从客户端回显给客户端,并在客户端输入“BYE”后关闭。但消息只在服务器关闭后出现在客户端上。Java Server在关闭后发送消息客户端

我会很感激,如果我能得到解决这个问题

这在服务器端代码:

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

回答

4

您有一个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'); 
    } 
+0

您的解决方案的工作,谢谢! – user2913212

相关问题