CS模式聊天室

User 类

public class User {
    private String name;
    private String ip;
    
    public User(String name,String ip) {
        this.name=name;
        this.ip=ip;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getIp() {
        return ip;
    }
    public void setIp(String ip) {
        this.ip = ip;
    }

}
 

Client

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.SystemColor;
import java.awt.TextArea;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.border.TitledBorder;
import javax.swing.text.BadLocationException;

import org.omg.PortableInterceptor.USER_EXCEPTION;

public class Client{
    private JFrame frame;
    private JList<String> userList;
    private JTextArea txt_Area;
    private JTextField txt_Field;
    private JTextField txt_prot;
    private JTextField txt_hostlp;
    private JTextField txt_name;
    private JButton btn_start;
    private JButton btn_stop;
    private JButton btn_send;
    private JPanel northJPanel;
    private JPanel southJPanel;
    private JScrollPane rightScroll;
    private JScrollPane leftJScroll;
    private JSplitPane centerSplit;
    private DefaultListModel<String> listModel;
    
    private boolean isConnected=false;
    private Socket socket;
    private PrintWriter writer;
    private BufferedReader reader;
    private MessageThread messageThread;
    private Map<String , User>onLineUsers=new HashMap<String,User>();
    
    
    public static void main(String[] args) {
        new Client();
    }
    
    // 执行发送  
    public void send() {  
        if (!isConnected) {  
            JOptionPane.showMessageDialog(frame, "还没有连接服务器,无法发送消息!", "错误",  
                    JOptionPane.ERROR_MESSAGE);  
            return;  
        }  
        String message = txt_Field.getText().trim();  
        if (message == null || message.equals("")) {  
            JOptionPane.showMessageDialog(frame, "消息不能为空!", "错误",  
                    JOptionPane.ERROR_MESSAGE);  
            return;  
        }  
        sendMessage(frame.getTitle() + "@" + "ALL" + "@" + message);  
        txt_Field.setText(null);  
    }  
public Client(){
    txt_Area=new JTextArea();
    txt_Area.setEditable(false);
    txt_Area.setFont(new Font("楷体",Font.PLAIN,20));
    txt_Area.setForeground(Color.black);
    txt_Field=new JTextField();
    txt_prot=new JTextField("7777");
    txt_hostlp=new JTextField("127.0.0.1");
    txt_name=new JTextField("HLH");
    btn_start=new JButton("连接");
    btn_send=new JButton("发送");
    btn_stop=new JButton("断开");
    listModel=new DefaultListModel<String>();
    userList=new JList<String>(listModel);
    northJPanel=new JPanel();
    northJPanel.setLayout(new GridLayout(1,7));
    northJPanel.add(new JLabel("端口"));
    northJPanel.add(txt_prot);
    northJPanel.add(new JLabel("服务器IP"));
    northJPanel.add(txt_hostlp);
    northJPanel.add(new JLabel("姓名"));
    northJPanel.add(txt_name);
    northJPanel.add(btn_start);
    northJPanel.add(btn_stop);
    northJPanel.setBorder(new TitledBorder("连接信息"));
    rightScroll=new JScrollPane(txt_Area);
    rightScroll.setBorder(new TitledBorder("消息显示区"));
    leftJScroll=new JScrollPane(userList);
    leftJScroll.setBorder(new TitledBorder("在线用户"));
    southJPanel=new JPanel(new BorderLayout());
    southJPanel.add(txt_Field,"Center");
    southJPanel.add(btn_send,"East");
    southJPanel.setBorder(new TitledBorder("写信息"));
    centerSplit=new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,leftJScroll,rightScroll);
    centerSplit.setDividerLocation(100);
    frame=new JFrame("客户端");
//    frame.setIconImage(Toolkit.getDefaultToolkit().createImage(Client.class.getResource("图片1.png")));
    frame.setLayout(new BorderLayout());
    frame.add(northJPanel,"North");
    frame.add(centerSplit,"Center");
    frame.add(southJPanel,"South");
    frame.setSize(700,500);
    int screen_w=Toolkit.getDefaultToolkit().getScreenSize().width;
    int screen_h=Toolkit.getDefaultToolkit().getScreenSize().height;
    frame.setLocation((screen_w-frame.getWidth())/2,(screen_h-frame.getHeight())/2);
    frame.setVisible(true);
    //更改颜色
    userList.setBackground(SystemColor.inactiveCaption);
    txt_Area.setBackground(SystemColor.inactiveCaption);
    southJPanel.setBackground(SystemColor.inactiveCaption);
    

    
    // 写消息的文本框中按回车键时事件  
    txt_Field.addActionListener(new ActionListener() {  
        public void actionPerformed(ActionEvent arg0) {  
            send();  
        }  
    });  

 // 单击发送按钮时事件  
    btn_send.addActionListener(new ActionListener() {  
        public void actionPerformed(ActionEvent e) {  
            send();  
        }  
    });  

    
    
    //单击断开按钮的事件
    btn_stop.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            if (!isConnected) {
                JOptionPane.showMessageDialog(frame, "已处于断开状态","错误",JOptionPane.ERROR_MESSAGE);
                return;
            }
            try {
                boolean flag=closeConnection();
                if (flag==false) {
                    throw new Exception("断开连接发生异常");
                }
                JOptionPane.showMessageDialog(frame, "成功断开");
            } catch (Exception exc) {
                JOptionPane.showMessageDialog(frame, exc.getMessage(),"错误",JOptionPane.ERROR_MESSAGE);
            }
        }
    });
    
    
    //单击连接按钮的事件
    btn_start.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            int port;
            if (isConnected) {
                JOptionPane.showMessageDialog(frame, "已处于连接状态","错误",JOptionPane.ERROR_MESSAGE);
                return;
            }
            try {
                try {
                    //获取端口文本框中的端口号去掉空格
                    port=Integer.parseInt(txt_prot.getText().trim());
                } catch (NumberFormatException e2) {
                    throw new Exception("端口号不符合要求,端口号为整数");
                }
                //获取IP地址文本框种的IP地址并去掉空格
                String hostIp=txt_hostlp.getText().trim();
                //获取姓名文本框中的姓名并去掉空格
                String name=txt_name.getText().trim();
                //判断是非为空
                if (name.equals("")||hostIp.equals("")) {
                    throw new Exception("姓名、服务器IP不能为空");
                }
                //连接服务器
                boolean flag=connectServer(port, hostIp, name);
                if (flag==false) {
                    throw new Exception("与服务器连接失败");
                }
                //标题改为用户名
                frame.setTitle(name);
                JOptionPane.showMessageDialog(frame, "成功连接");
            } catch (Exception exc) {
                JOptionPane.showMessageDialog(frame,exc.getMessage(),"错误",JOptionPane.ERROR_MESSAGE);
            }
        }
    });
    
    // 关闭窗口时事件  
    frame.addWindowListener(new WindowAdapter() {  
        public void windowClosing(WindowEvent e) {  
            if (isConnected) {  
                closeConnection();// 关闭连接  
            }  
            System.exit(0);// 退出程序  
        }  
    });  

}


public boolean connectServer(int port,String hostIp,String name){
    //连接服务器
    try {
        socket=new Socket(hostIp,port);
        writer=new PrintWriter(socket.getOutputStream());
        reader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
        sendMessage(name+"@"+socket.getLocalAddress().toString());
        messageThread=new MessageThread(reader, txt_Area);
        messageThread.start();
        isConnected=true;
        return true;
    } catch (Exception e) {
        txt_Area.append("与端口号为:"+port+"IP地址为:"+hostIp+"的服务器连接失败"+"\r\n");
        isConnected=false;
        return false;
    }
}

public void sendMessage(String message) {
    writer.println(message);
    writer.flush();
}

public synchronized boolean closeConnection() {  
    try {  
        sendMessage("CLOSE");// 发送断开连接命令给服务器  
        messageThread.stop();// 停止接受消息线程  
        // 释放资源  
        if (reader != null) {  
            reader.close();  
        }  
        if (writer != null) {  
            writer.close();  
        }  
        if (socket != null) {  
            socket.close();  
        }  
        isConnected = false;  
        return true;  
    } catch (IOException e1) {  
        e1.printStackTrace();  
        isConnected = true;  
        return false;  
    }  
}  


//不断接受消息的线程内部类
class MessageThread extends Thread{
    private BufferedReader reader;
    private JTextArea txt_Area;
    
    //接收信息的线程构造方法
    public MessageThread(BufferedReader reader,JTextArea txt_Area) {
        this.reader=reader;
        this.txt_Area=txt_Area;
    }
    
    //被动关闭连接
    public synchronized void closeCon() throws Exception{
        listModel.removeAllElements();
        if (reader!=null) {
            reader.close();
        }
        if (writer!=null) {
            writer.close();
        }
        if (socket!=null) {
            socket.close();
        }
        isConnected=false;
    }
    public void run() {
        String message="";
                while(true) {
                    try {
                        message=reader.readLine();
                        StringTokenizer stringTokenizer =new StringTokenizer(message,"/@");
                        String command=stringTokenizer.nextToken();
                        //服务器关闭命令
                        if (command.equals("CLOSE")) {
                            txt_Area.append("服务器已关闭\r\n");
                            closeCon();
                            return;//结束线程
                        }else if (command.equals("ADD")) {
                            String username="";
                            String userIp="";
                            if ((username=stringTokenizer.nextToken())!=null&&(userIp=stringTokenizer.nextToken())!=null) {
                                User user=new User(username,userIp);
                                onLineUsers.put(username, user);
                                listModel.addElement(username);}
                            }else if (command.equals("DELETE")) {
                                String username=stringTokenizer.nextToken();
                                User user=(User)onLineUsers.get(username);
                                onLineUsers.remove(user);
                                listModel.removeElement(username);
                            }else if (command.equals("USERLIST")) {
                                int size=Integer.parseInt(stringTokenizer.nextToken());
                                 String username=null;
                                 String userIp=null;
                                for(int i=0;i<size;i++) {
                                    username=stringTokenizer.nextToken();
                                    userIp=stringTokenizer.nextToken();
                                    User user=new User(username,userIp);
                                    onLineUsers.put(username, user);
                                    listModel.addElement(username);
                                }
                            }else if (command.equals("MAX")) {
                                txt_Area.append(stringTokenizer.nextToken()+stringTokenizer.nextToken()+"\r\n");
                                closeCon();
                                JOptionPane.showMessageDialog(frame, "服务器缓冲区已满","错误",JOptionPane.ERROR_MESSAGE);
                                return;
                            }else {
                                txt_Area.append(message+"\r\n");
                            }
                        }catch (IOException e) {
                            e.printStackTrace();
                        }catch (Exception e) {
                            e.printStackTrace();
                        }
                }
            }
        }
}

Server

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.SystemColor;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Reader;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.StringTokenizer;

import javax.imageio.ImageIO;
import javax.swing.DefaultListModel;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
import javax.swing.border.TitledBorder;
import javax.tools.Tool;

import org.omg.CORBA.PUBLIC_MEMBER;

public class Server {
    private JFrame frame;
    private JPanel centerJPanel;
    private JLabel lab_inf;
    private JTextArea contentArea;
    private JTextField txt_msg;
    private JTextField txt_max;
    private JTextField txt_port;
    private JTextField txt_remove;
    private JButton btn_start;
    private JButton btn_stop;
    private JButton btn_send;
    private JButton btn_remove;
    private JPanel northPanel;
    private JPanel southPanel;
    private JScrollPane rightpanel;
    private JScrollPane leftpanel;
    private JSplitPane centersplit;
    private JList<String>userList;
    private DefaultListModel<String>listModel;
    
    private ServerSocket serverSocket;
    private ServerThread serverThread;
    private ArrayList<ClientThread>clients;
    private boolean isStart=false;
    
    

    public static void main(String[] args) {
        new Server();
        }
    
    // 执行消息发送  
    public void send() {  
        if (!isStart) {  
            JOptionPane.showMessageDialog(frame, "服务器还未启动,不能发送消息!", "错误",  
                    JOptionPane.ERROR_MESSAGE);  
            return;  
        }  
        if (clients.size() == 0) {  
            JOptionPane.showMessageDialog(frame, "没有用户在线,不能发送消息!", "错误",  
                    JOptionPane.ERROR_MESSAGE);  
            return;  
        }  
        String message = txt_msg.getText().trim();  
        if (message == null || message.equals("")) {  
            JOptionPane.showMessageDialog(frame, "消息不能为空!", "错误",  
                    JOptionPane.ERROR_MESSAGE);  
            return;  
        }  
        sendServerMessage(message);// 群发服务器消息  
        contentArea.append("服务器:" + txt_msg.getText() + "\r\n");  
        txt_msg.setText(null);  
    }
    
public Server() {
    frame=new JFrame("服务器");
//    frame.setIconImage(Toolkit.getDefaultToolkit().createImage(Client.class.getResource("图片2.png")));
//    frame.setIconImage(Toolkit.getDefaultToolkit().createImage(Server.class.getResource("图片2.png")));

    contentArea=new JTextArea();
    contentArea.setEditable(false);
    contentArea.setForeground(Color.BLUE);
    contentArea.setFont(new Font("楷体",Font.BOLD,20));
    txt_msg=new JTextField();
    txt_max=new JTextField("30");
    txt_remove=new JTextField();
    txt_port=new JTextField("7777");
    btn_start=new JButton("启动");
    btn_stop=new JButton("停止");
    btn_send=new JButton("发送");
    btn_remove=new JButton("移除用户");
    btn_stop.setEnabled(false);
    listModel=new DefaultListModel<String>();
    userList=new JList<String>(listModel);
    
    southPanel=new JPanel(new BorderLayout());
    southPanel.setBorder(new TitledBorder("写消息"));
    southPanel.add(txt_msg,"Center");
    southPanel.add(btn_send,"East");
    leftpanel=new JScrollPane(userList);
    leftpanel.setBorder(new TitledBorder("在线用户"));

    
    rightpanel=new JScrollPane(contentArea);
    rightpanel.setBorder(new TitledBorder("消息显示区"));
    centersplit=new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,leftpanel,rightpanel);
    centersplit.setDividerLocation(100);
    northPanel=new JPanel();
    northPanel.setLayout(new GridLayout(1,7));
    northPanel.add(new JLabel("    人数上限"));
    northPanel.add(txt_max);
    northPanel.add(new JLabel("        端口"));
    northPanel.add(txt_port);
    northPanel.add(btn_start);
    northPanel.add(btn_stop);
    northPanel.add(txt_remove);
    northPanel.add(btn_remove);
    northPanel.setBorder(new TitledBorder(" "));
    
    new JFrame("ester egg");
    centerJPanel=new JPanel(new BorderLayout());
    lab_inf=new JLabel("Phone:13628413571\r\nOICQ:1045507205\r\nVX:Shisui1412");
    lab_inf.setText("<html>Name:HLH<br>Phone:13628413571<br>OICQ:1045507205<br>VX:Shisui1412<html>");
    centerJPanel.add(lab_inf,"Center");
    lab_inf.setFont(new Font("宋体",Font.BOLD,30));

    
    //更改颜色
    userList.setBackground(SystemColor.inactiveCaption);
    contentArea.setBackground(SystemColor.inactiveCaption);
    southPanel.setBackground(SystemColor.inactiveCaption);
    
    frame.setLayout(new BorderLayout());
    frame.add(northPanel,"North");
    frame.add(centersplit,"Center");
    frame.add(southPanel,"South");
    frame.setSize(750,400);
    int screen_w=Toolkit.getDefaultToolkit().getScreenSize().width;
    int screen_h=Toolkit.getDefaultToolkit().getScreenSize().height;
    frame.setLocation((screen_w-frame.getWidth())/2,(screen_h-frame.getHeight())/2);
    frame.setVisible(true);
    
    // 关闭窗口时事件  
    frame.addWindowListener(new WindowAdapter() {  
        public void windowClosing(WindowEvent e) {  
            if (isStart) {  
                closeServer();// 关闭服务器  
            }  
            System.exit(0);// 退出程序  
        }  
    });  
    
     
 // 文本框按回车键时事件  
    txt_msg.addActionListener(new ActionListener() {  
        public void actionPerformed(ActionEvent e) {  
            send();  
        }  
    });  
    
 // 单击发送按钮时事件  
    btn_send.addActionListener(new ActionListener() {  
        public void actionPerformed(ActionEvent arg0) {  
            send();  
        }  
    });  
    
  //移除用户
    btn_remove.addActionListener (new ActionListener(){
        @Override
        public void actionPerformed(ActionEvent e) {

            for (int i = clients.size() - 1; i >= 0; i--) {
                if (clients.get (i).getUser ().getName ().equals (txt_remove.getText ())) {
                    contentArea.append("用户"+txt_remove.getText()+"已移除"+"\r\n");
                    JOptionPane.showMessageDialog(frame, "移除成功");


                    ClientThread temp = clients.get(i);
                    temp.getWriter().println("CLOSE");
                    temp.getWriter().flush();
                    listModel.removeElement (txt_remove.getText ());
                    for (int j = clients.size() - 1; j >= 0; j--){
                        if(temp!=clients.get (j)){
                            clients.get (j).getWriter ().println ("DELETE/@"+temp.getUser ().getName ());
                            clients.get (j).getWriter ().flush ();
                        }
                    }
                    clients.remove(i);// 删除此用户的服务线程
                    temp.stop();// 停止这条服务线程
                    return;
                }
            }
            contentArea.append("用户"+txt_remove.getText()+" 移除失败 ,因为没找到要移除的用户"+"\r\n");
            JOptionPane.showMessageDialog(frame, "移除失败 ,因为没找到要移除的用户");
        }

        private void sendOutMessage(String string, String text) {
            // TODO Auto-generated method stub
            
        }
    });
    
    //单击停止服务器按钮时事件  
    btn_stop.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            if (!isStart) {
                JOptionPane.showMessageDialog(frame, "服务器还未启动","错误",JOptionPane.ERROR_MESSAGE);
                return;
            }
            try {
                closeServer();
                btn_start.setEnabled(true);
                txt_max.setEnabled(true);
                txt_port.setEnabled(true);
                btn_stop.setEnabled(false);
                contentArea.append("服务器成功停止\r\n");
                JOptionPane.showMessageDialog(frame, "服务器成功停止");
            } catch (Exception exc) {
                JOptionPane.showMessageDialog(frame, "停止服务器发生异常","错误",JOptionPane.ERROR_MESSAGE);
            }
        }
    });
    
    //单击启动服务器按钮时事件  
    btn_start.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            if(isStart) {
                JOptionPane.showMessageDialog(frame, "服务器已启动","错误", JOptionPane.ERROR_MESSAGE);
                return;
            }
            int max,port;
            try {
                try {
                    max=Integer.parseInt(txt_max.getText());
                }catch (Exception e1) {
                    throw new Exception("人数上限为数字");
                }
                if (max<=0) {
                    throw new Exception("人数上限为正整数");
                }
                try {
                    port =Integer.parseInt(txt_port.getText());
                } catch (Exception e1) {
                    throw new Exception("端口号为正整数");
                }
                if (port<=0) {
                    throw new Exception("端口号为正整数");
                }
                serverStart(max, port);
                contentArea.append("服务器成功启动。人数上限:"+max+",端口:"+port+"\r\n");
                JOptionPane.showMessageDialog(frame, "服务器成功启动");
                btn_start.setEnabled(false);
                txt_max.setEnabled(false);
                txt_port.setEnabled(false);
                btn_stop.setEnabled(true);
            }catch (Exception e1) {
                JOptionPane.showMessageDialog(frame, e1.getMessage(),"错误",JOptionPane.ERROR_MESSAGE);
                
            }
        }
    });
}

//启动服务器
public void serverStart(int max,int port)throws java.net.BindException{
    try {
        clients=new ArrayList<ClientThread>();
        serverSocket=new ServerSocket(port);
        serverThread=new ServerThread(serverSocket,max);
        serverThread.start();
        isStart=true;
    } catch (BindException e) {
        isStart=true;
        throw new BindException("端口已占用");
    }catch (Exception e1) {
        e1.printStackTrace();
        isStart=false;
        throw new BindException("启动服务器异常");
    }
}

//关闭服务器
public void closeServer() {
    try {
        if(serverThread!=null)
            serverThread.stop();
        
        for (int i = clients.size() - 1; i >= 0; i--) {  
            // 给所有在线用户发送关闭命令  
            clients.get(i).getWriter().println("CLOSE");  
            clients.get(i).getWriter().flush();  
            // 释放资源  
            clients.get(i).stop();// 停止此条为客户端服务的线程  
            clients.get(i).reader.close();  
            clients.get(i).writer.close();  
            clients.get(i).socket.close();  
            clients.remove(i);  
        }  
        if (serverSocket != null) {  
            serverSocket.close();// 关闭服务器端连接  
        }  
        listModel.removeAllElements();// 清空用户列表  
        isStart = false;  
    } catch (IOException e) {  
        e.printStackTrace();  
        isStart = true;  
    }  
}  


// 群发服务器消息  
public void sendServerMessage(String message) {  
    for (int i = clients.size() - 1; i >= 0; i--) {  
        clients.get(i).getWriter().println("服务器:" + message + "(群发)");  
        clients.get(i).getWriter().flush();  
    }  
}  

//服务器线程
class ServerThread extends Thread{
    private ServerSocket serverSocket;
    private int max;
    public ServerThread(ServerSocket serverSocket,int max) {
        this.serverSocket=serverSocket;
        this.max=max;
    }
    public void run() {
        while(true) {
            try {
                Socket socket=serverSocket.accept();
                System.out.println(clients.size());
                if (clients.size()==max) {
                    BufferedReader r=new BufferedReader(new InputStreamReader(socket.getInputStream()));
                    PrintWriter w=new PrintWriter(socket.getOutputStream());
                    String inf=r.readLine();
                    StringTokenizer st=new StringTokenizer(inf,"@");
                    User user=new User(st.nextToken(),st.nextToken());
                    w.print("MAX@服务器:对不起,"+user.getName()+user.getIp()+",服务器在线人数已达上限");
                    w.flush();
                    r.close();
                    w.close();
                    socket.close();
                    continue;
                }
                ClientThread client=new ClientThread(socket);
                client.start();
                clients.add(client);
                listModel.addElement(client.getUser().getName());
                contentArea.append(client.getUser().getName()+client.getUser().getIp()+"上线\r\n");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

//为一个客户端服务的线程  
class ClientThread extends Thread{
    private Socket socket;
    private BufferedReader reader;
    private PrintWriter writer;
    private User user;
    
    
    
    public BufferedReader getReader() {
        return reader;
    }
    public PrintWriter getWriter() {
        return writer;
    }
    public User getUser() {
        return user;
    }
    public ClientThread(Socket socket) {
        try {
            this.socket=socket;
            reader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
            writer=new PrintWriter(socket.getOutputStream());
            String inf=reader.readLine();
            StringTokenizer st=new StringTokenizer(inf,"@");
            user=new User(st.nextToken(),st.nextToken());
            writer.println(user.getName()+user.getIp()+"与服务器连接成功");
            writer.println("使用[#用户名 聊天内容]可以进行私聊");
            writer.flush();
            if (clients.size()>0) {
                String temp="";
                for (int i = clients.size()-1; i >=0; i--) {
                    temp+=(clients.get(i).getUser().getName()+"/"+clients.get(i).getUser().getIp())+"@";
                }
                    writer.println("USERLIST@"+clients.size()+"@"+temp);
                    writer.flush();
                }
                for (int i = clients.size()-1; i>=0; i--) {
                    clients.get(i).getWriter().println("ADD@"+user.getName()+user.getIp());
                    clients.get(i).getWriter().flush();
                }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
public void run() {
    String message=null;
    while(true) {
        try {
            message=reader.readLine();
            if(message.equals("CLOSE")) {
                contentArea.append(this.getUser().getName()+this.getUser().getIp()+"下线\r\n");
                reader.close();
                writer.close();
                socket.close();
                
                for (int i = clients.size()-1; i >=0; i--) {
                    clients.get(i).getWriter().println("DELETE@"+user.getName());
                    clients.get(i).getWriter().flush();
                }
                listModel.removeElement(user.getName());
                for (int i = clients.size()-1; i >=0 ; i--) {
                    if (clients.get(i).getUser()==user) {
                        ClientThread temp=clients.get(i);
                        clients.remove(i);
                        temp.stop();
                        return;
                    }
                }
            }else {
                dispatcherMessage(message);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


//转发消息  
public void dispatcherMessage(String message) {  
    StringTokenizer stringTokenizer = new StringTokenizer(message, "@");  
    String source = stringTokenizer.nextToken();  
    String owner = stringTokenizer.nextToken();  
    String content = stringTokenizer.nextToken(); 
    String toUser="";
    String fromUser=message.split("@")[0];
    int fromIndex=-1;
    int toIndex=-1;
    if (content.startsWith("#")) {
        toUser=content.split(" ")[0].substring(1);
        for (int i = clients.size()-1; i >=0; i--) {
            if (clients.get(i).getUser().getName().equals(toUser)) {
                toIndex=i;
                clients.get(i).getWriter().println(fromUser+"对你说:"+content.split(" ")[1]+"(私聊)");
                clients.get(i).getWriter().flush();    
        }
    }
    for (int j = clients.size()-1; j >=0; j--) {
        if (clients.get(j).getUser().getName().equals(fromUser)) {
            fromIndex=j;
            if (toIndex==-1) {
                clients.get(fromIndex).getWriter().println("你私聊的对象不存在");
                clients.get(j).getWriter().flush();
            }else {
                clients.get(j).getWriter().println("你对"+toUser+"说:"+content.split(" ")[1]+"(私聊)");
                clients.get(j).getWriter().flush();
            }
        }
    }
    }else if (content.equals("INAEE1412")) { // 小彩蛋
        JFrame frame1 = new JFrame("Easter egg");
        frame1.setSize(500,500);
        frame1.setVisible(true);
        frame1.add(lab_inf);
         } else{
    message = source + "说:" + content;  
    contentArea.append(message + "\r\n");  
    if (owner.equals("ALL")) {// 群发  
        for (int i = clients.size() - 1; i >= 0; i--) {  
            System.out.println(i);
            clients.get(i).getWriter().println(message + "(群发)");  
            clients.get(i).getWriter().flush();  
        }  
    }  
    }
}
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值