客户端类: //import java.awt.BorderLayout; //import java.awt.Frame; //import java.awt.TextArea; //import java.awt.TextField; //import java.awt.event.WindowAdapter; //Alt+Shift+R 重命名 (是我自己最爱用的一个了,尤其是变量和类的Rename,比手工方法能节省很多劳动力) //Alt+Shift+M 抽取方法 (这是重构里面最常用的方法之一了,尤其是对一大堆泥团代码有用) //Ctrl+Shift+F4 关闭所有打开的Editer //Ctrl+W 关闭当前Editer //Ctrl+K 参照选中的Word快速定位到下一个 //Ctrl+Q 定位到最后编辑的地方 //Ctrl+L 定位在某行 (对于程序超过100的人就有福音了) //Ctrl+M 最大化当前的Edit或View (再按则反之) //Alt+Shift+F 把Class中的local变量变为field变量 (比较实用的功能) import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; /** * 客户端类 * * @author heyuanbo * */ public class ChatClient extends Frame { private boolean connected = false; private DataInputStream dataInputStream = null; private DataOutputStream dataOutputStream = null; private Socket socket = null; private TextField tfText = new TextField(); private TextArea textArea = new TextArea(); // 程序入口 public static void main(String[] args) { new ChatClient().launchFrame(); } // 窗体加载 public void launchFrame() { setLocation(400, 300); this.setSize(300, 300); add(tfText, BorderLayout.SOUTH); add(textArea, BorderLayout.NORTH); pack(); this.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { closeConn(); ((Window) e.getComponent()).dispose(); System.out.println("client system exit!"); // 测试语句 System.exit(0); } }); tfText.addActionListener(new TextFieldListener()); setVisible(true); connect(); new Thread(new RecvThread()).start(); } // 获得连接 private void connect() { try { socket = new Socket("127.0.0.1", 8989); dataInputStream = new DataInputStream(socket.getInputStream()); dataOutputStream = new DataOutputStream(socket.getOutputStream()); System.out.println("connected!"); // 测试语句 connected = true; } catch (ConnectException e) { System.out.println("ConnectException...connection not open!"); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } // 关闭连接,清空缓冲区 private void closeConn() { try { dataOutputStream.close(); dataInputStream.close(); socket.close(); } catch (NullPointerException e) { System.out.println("NullPointerException..."); } catch (IOException e) { e.printStackTrace(); } } // 内部类 private class TextFieldListener implements ActionListener { public void actionPerformed(ActionEvent e) { String str = tfText.getText().trim(); tfText.setText(""); try { dataOutputStream.writeUTF(str); dataOutputStream.flush(); } catch (IOException e1) { e1.printStackTrace(); } } } // 线程类 private class RecvThread implements Runnable { public void run() { try { while (connected) { String str = dataInputStream.readUTF(); System.out.println("测试语句:" + str); // 测试语句 textArea.setText(textArea.getText() + str + "/n"); } } catch (SocketException e) { System.out.println("SocketException...本客户端退出了,bye!"); } catch (EOFException e) { System.out.println("EOFException...本客户端退出了,bye - bye!"); } catch (IOException e) { e.printStackTrace(); } } } } 服务器端类: import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.EOFException; import java.io.IOException; import java.net.*; import java.util.ArrayList; import java.util.List; import javax.swing.Renderer; import com.sun.jmx.remote.internal.ClientCommunicatorAdmin; /** * 服务器端类 * * @author heyuanbo * */ public class ChatServer { private boolean started = false; // 是否启动服务 private ServerSocket serverSocket = null; List<Client> clients = new ArrayList<Client>(); public static void main(String[] args) { new ChatServer().start(); // ChatServer.Client client = new ChatServer().new Client(); } private void start() { try { serverSocket = new ServerSocket(8989); started = true; System.out.println("started1"); // 测试语句 } catch (BindException e) { System.out.println("端口使用中。。。"); System.out.println("请先关闭相关程序!"); System.exit(0); } catch (IOException e) { e.printStackTrace(); } try { int i = 0; // 测试语句 while (started) { System.out.println("started2"); // 测试语句 Socket socket = serverSocket.accept(); System.out.println("started3"); // 测试语句 为什么没有输出? Client client = new Client(socket); i++; System.out.println("第 " + i + " 个client connected!"); // 测试语句 new Thread(client).start(); clients.add(client); System.out.println("clients.size():" +clients.size()); // 测试语句 } } catch (IOException e) { e.printStackTrace(); } finally { try { if (serverSocket != null) { serverSocket.close(); serverSocket = null; } } catch (IOException e) { e.printStackTrace(); } } } private class Client implements Runnable { private boolean connected = false; // 是否连接成功 private Socket socket = null; private DataInputStream dataInputStream = null; private DataOutputStream dataOutputStream = null; public Client() { } public Client(Socket socket) { this.socket = socket; try { dataInputStream = new DataInputStream(socket.getInputStream()); dataOutputStream = new DataOutputStream(socket .getOutputStream()); connected = true; } catch (IOException e) { e.printStackTrace(); } } public void sendMessage(String str) { try { dataOutputStream.writeUTF(str); } catch (NullPointerException e) { System.out.println("NullPointerException...删除已关闭的客户端"); }catch (IOException e) { clients.remove(this); System.out.println("IOException...删除已关闭的客户端"); e.printStackTrace(); } } public void run() { System.out.println("123456"); // 测试语句 try { while (connected) { String str = dataInputStream.readUTF(); System.out.println(str); // 测试语句 for (int i = 0; i < clients.size(); i++) { Client client = clients.get(i); client.sendMessage(str); } } } catch (EOFException e) { System.out.println("Client closed!"); } catch (IOException e) { e.printStackTrace(); } finally { try { if (dataInputStream != null) { dataInputStream.close(); dataInputStream = null; } if (dataOutputStream != null) { dataOutputStream.close(); dataOutputStream = null; } if (socket != null) { socket.close(); socket = null; } } catch (Exception e) { e.printStackTrace(); } } } } }