为什么这个聊天程序刚开始时的聊天内容不同步,而且刚开始时的内容还会丢失import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import java.util.logging.Level;
import java.util.logging.Logger;public class ChatClient extends Frame {    TextField text = new TextField();
    TextArea area = new TextArea();
    DataOutputStream dos = null;
    DataInputStream dis = null;
    Socket s = null;
    Thread recive = new Thread(new ReciveThread());
    boolean isconnect = false;    public static void main(String[] args) {
        new ChatClient().Lanuch();
    }    private void Lanuch() {        this.add(text, BorderLayout.SOUTH);
        this.add(area, BorderLayout.NORTH);
        text.addActionListener(new textListener());
        this.setLocation(100, 200);
        this.setSize(100, 300);
        this.pack();
        this.setVisible(true);        this.addWindowListener(new WindowAdapter() {            public void windowClosing(WindowEvent args) {
                disconnect();
                System.exit(0);
            }
        });        connect(); //连接服务器
        recive.start();
    }    private class textListener implements ActionListener {        public void actionPerformed(ActionEvent e) {
            String str = text.getText().trim();
            //area.setText(area.getText() + str + "\n");
            text.setText(null);
             try {
//System.out.println(s);
                dos.writeUTF(str);
                dos.flush();
                //dos.close();
            } catch (IOException e1) {
                e1.printStackTrace();
            }        }
    }    public void connect() {
        try {
            s = new Socket("127.0.0.1", 8888);
            dis = new DataInputStream(s.getInputStream());
            dos = new DataOutputStream(s.getOutputStream());
            System.out.println("已连接到服务器");
            isconnect = true;
        } catch (UnknownHostException ex) {
            Logger.getLogger(ChatClient.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(ChatClient.class.getName()).log(Level.SEVERE, null, ex);
        }
    }    public void disconnect() {
        try {
            dos.close();
            dis.close();
        } catch (IOException ex) {
            Logger.getLogger(ChatClient.class.getName()).log(Level.SEVERE, null, ex);
        }
    }    private class ReciveThread implements Runnable {        public void run() {
            try {
                while (isconnect) {
                    String str = dis.readUTF();
                    area.setText(area.getText() + str + "\n");
                }
            } catch (SocketException se) {
                System.out.println("有个客户端退出了!");
            } catch (EOFException e) {
                System.out.println("程序非正常退出!");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
import java.io.*;
import java.net.*;
import java.util.*;public class ChatServer {    ServerSocket ss = null;
    List<Client> clients = new ArrayList();
    boolean start = false;    private void begin() {
        try {
            ss = new ServerSocket(8888);
            start = true;
        } catch (BindException e) {
            System.out.println("端口使用中....");
            System.out.println("请关掉相关程序并重新运行服务器!");
            System.exit(0);
        } catch (IOException e) {
            e.printStackTrace();
        }        try {
            while (start) {
                Socket s = ss.accept();
                Client c = new Client(s);
                System.out.println("有客户端连接到主机");
                new Thread(c).start();
                clients.add(c);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                ss.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }    }    private class Client implements Runnable {        private Socket s;
        private DataInputStream dis = null;
        private DataOutputStream dos = null;
        private boolean bConnected = false;        public Client(Socket s) {
            this.s = s;
            try {
                dis = new DataInputStream(s.getInputStream());
                dos = new DataOutputStream(s.getOutputStream());
               System.out.println(dis.readUTF());
                bConnected = true;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }        public void send(String str) {
            try {
                dos.writeUTF(str);
            } catch (IOException e) {
                clients.remove(this);
                System.out.println("有个客户端退出了!");
                //e.printStackTrace();
            }
        }        public void run() {
            try {
                while (bConnected) {
                    String str = dis.readUTF();
                    System.out.println(str);
                    for (int i = 0; i < clients.size(); i++) {
                        Client c = clients.get(i);
                        c.send(str);
//System.out.println(" a string send !");
                    }
                }
            } catch (EOFException e) {
                System.out.println("Client closed!");
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (dis != null) {
                        dis.close();
                    }
                    if (dos != null) {
                        dos.close();
                    }
                    if (s != null) {
                        s.close();
                        //s = null;
                    }                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }
    }    public static void main(String[] args) {
        new ChatServer().begin();
    }
}

解决方案 »

  1.   

    你应该用线程来实现
    connect方法的内容放在一个线程类中
    fulsh方法 也放在线程类里
      

  2.   

    你连接按钮和发送按钮用同一个事件类,并接收一个JFrame对象,在JFrame中的area和textField都设为成员变量并实现get方法.addActioinListener的时候把this传给它。
    用e.getSorse()方法判断是单击了哪个按钮,把input output都设为成员变量,单击连接的时候建一个Socket,并建一个线程类while(true)不停的读取并设置area中的内容单击发送的时候 outputStream.write();因为你这个事件类执有一个JFrame对象 所有可以得到JFrame中的文本框和文本域中的内容.接着就只要得到textField中的内容再用write写出,append方法设置area的内容不过最好还是把按钮和其它的组件放在一个JPanel中再把JPanel放到一个JFrame中
    Frame 和Panel分两个类来写 比较清晰
      

  3.   

    你先把结构整一下
    让思路清晰一点 
    我写了一个例子
    把监听类和界面类分开来,界面分为JPanel 和JFrameimport java.awt.BorderLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JTextArea;//JPanel单独建一个类,并可以把组件设为成员变量,生成get方法
    class TestJPanel extends JPanel {
    private JButton send;
    private JButton client;
    private JTextArea area; public TestJPanel() {
    send = new JButton("发送");
    client = new JButton("连接");

    //给两个按钮添加事件时,把this传过去
    ClientButtonsListener listener = new ClientButtonsListener(this);
    send.addActionListener(listener);
    client.addActionListener(listener);

    area = new JTextArea();
    JPanel tempJPanel = new JPanel();
    tempJPanel.add(send);
    tempJPanel.add(client); this.setLayout(new BorderLayout());
    this.add(tempJPanel, BorderLayout.NORTH);
    this.add(area, BorderLayout.CENTER);
    }
    public JButton getSend() {
    return send;
    }
    public JButton getClient() {
    return client;
    }
    public JTextArea getArea() {
    return area;
    }
    }//再写一个监听类,监听界面中的所有按钮 
    class ClientButtonsListener implements ActionListener {

    //在监听类中接收一个窗体对象
    private TestJPanel panel;
    public ClientButtonsListener(TestJPanel panel) {
    this.panel = panel;
    }
    public void actionPerformed(ActionEvent e) {

    // 通过e.getSourse()方法判断单击的是哪个按钮
    if(e.getSource() == panel.getSend()){
    System.out.println("单击发送按钮时");
    }else if(e.getSource() == panel.getClient()){
    System.out.println("单击连接按钮时");
    }
    }
    }// 界面分为JFrame和JPanel JFrame中嵌套JPanel
    public class ChatClient extends JFrame {
    private TestJPanel panel;
    public ChatClient() {
    panel = new TestJPanel();
    this.setTitle("Client");
    this.setSize(300, 300);
    this.setLocationRelativeTo(null);// 居中
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.add(panel); this.setVisible(true);
    }
    public static void main(String[] args) {
    new ChatClient();
    }
    }