java socket简易聊天室

对学完java socket的朋友有一定的帮助,因为当你学好这方面的知识后,想必也有做着玩玩的念头!如下:

项目图参照
这里写图片描述
User类

 package hfz.addAction.cn;


//用户信息类
 public class User{
        private String name;

    public User(String name) {
         this.name = name;
    }

    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;
     }*/
}

注册块
这里写图片描述

package hfz.Register.cn;

public class Register extends JFrame implements ActionListener{
    JLabel labelName,labelName1;
    JLabel labelSex,labelSex1;
    JLabel labelPassword1,labelPassword11;
    JLabel labelPassword2,labelPassword22;
    ButtonGroup bg=new ButtonGroup();    //性别2个放一起选择
    JTextField textName;
    JRadioButton radioBoy;
    JRadioButton radioGirl;
    JLabel logoimagePosition1=new JLabel();
    JLabel logoimagePosition2=new JLabel();

    JPasswordField textPassword1;
    JPasswordField textPassword2;

    JButton b1;
    JButton b2;
    JButton b3;
    JPanel Panel=new JPanel();
    JLabel imagePos;


    public Register()
    {
        this.setTitle(" 用户注册");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(530,300);

        //窗口居中
        Dimension us = this.getSize();
        Dimension them = Toolkit.getDefaultToolkit().getScreenSize();
        int X = (them.width - us.width) / 2 ;
        int Y = (them.height - us.height) / 2 ;     
        this.setLocation(X,Y);
        getContentPane().add(Panel);
        Panel.setLayout(null);    //设置框架窗口的布局管理器为null

        //添加组件
        Font f = new Font("宋体",Font.PLAIN,12);
        labelName = new JLabel("用户名:");
        labelName.setFont(f);
        labelName1 = new JLabel("(用户名长度限制为2-15字节)");
        labelName1.setFont(f);
        labelSex = new JLabel("性  别:");
        labelSex.setFont(f);
        labelSex1 = new JLabel("(请选择您的性别)");
        labelSex1.setFont(f);
        labelPassword1 = new JLabel("口  令:");
        labelPassword1.setFont(f);
        labelPassword11 = new JLabel("(密码不得少于6个字符多于12个字符)");
        labelPassword11.setFont(f);
        labelPassword2 = new JLabel("口  令:");
        labelPassword2.setFont(f);
        labelPassword22 = new JLabel("(请再输一遍确认)");
        labelPassword22.setFont(f);
        radioBoy = new JRadioButton("男 生");
        radioBoy.setBackground(new Color(150,205,155));
        radioBoy.setSelected(true);
        bg.add(radioBoy);

        radioGirl = new JRadioButton("女 生");
        radioGirl.setBackground(new Color(150,205,155));
        bg.add(radioGirl);

        textName = new JTextField(10);
        textName.setToolTipText("☆请输入您要注册的用户名☆");
        textPassword1 = new JPasswordField(10);
        textPassword1.setToolTipText("☆请输入您的密码☆");
        textPassword2 = new JPasswordField(10);
        textPassword2.setToolTipText("☆请再次输入密码确认☆");

        b1 = new JButton("提   交");
        b1.setBackground(new Color(0,155,0));
        b1.addActionListener(this);
        b2 = new JButton("重   置");
        b2.setBackground(new Color(0,155,0));
        b2.addActionListener(this);
        b3 = new JButton("返   回");
        b3.setBackground(new Color(0,155,0));
        b3.addActionListener(this);
        //背景
        Icon image = new ImageIcon("image/2.jpg");
        imagePos = new JLabel(image);

        //手工设置各个组件的位置和大小
        labelName.setBounds(new Rectangle(40, 20, 60, 20));
        textName.setBounds(new Rectangle(100, 20, 180, 20));
        labelName1.setBounds(new Rectangle(300, 20, 200, 20));
        labelSex.setBounds(new Rectangle(40, 55, 60, 20));
        radioBoy.setBounds(new Rectangle(95, 55, 55, 20));
        logoimagePosition1.setBounds(new Rectangle(150, 52, 30, 25));
        radioGirl.setBounds(new Rectangle(185, 55, 55, 20));
        logoimagePosition2.setBounds(new Rectangle(245, 52, 30, 25));
        labelSex1.setBounds(new Rectangle(300, 54, 150, 25));
        labelPassword1.setBounds(new Rectangle(40, 85, 60, 20));
        textPassword1.setBounds(new Rectangle(100, 85, 180, 20));
        labelPassword11.setBounds(new Rectangle(300, 85, 220, 20));
        labelPassword2.setBounds(new Rectangle(40, 120, 60, 20));
        textPassword2.setBounds(new Rectangle(100, 120, 180, 20));
        labelPassword22.setBounds(new Rectangle(300, 120, 220, 20));
        b1.setBounds(new Rectangle(60, 210, 80, 25));
        b2.setBounds(new Rectangle(170,210, 80, 25));
        b3.setBounds(new Rectangle(280, 210, 80, 25));

        imagePos.setBounds(new Rectangle(0,0,530,300));
        //添加组件到面板
        Panel.add(labelName);
        Panel.add(textName);
        Panel.add(labelName1);
        Panel.add(labelSex);
        Panel.add(radioBoy);
        Panel.add(logoimagePosition1);
        Panel.add(radioGirl);
        Panel.add(logoimagePosition2);
        Panel.add(labelSex1);
        Panel.add(labelPassword1);
        Panel.add(textPassword1);
        Panel.add(labelPassword11);
        Panel.add(labelPassword2);
        Panel.add(textPassword2);
        Panel.add(labelPassword22);
        Panel.add(b1);
        Panel.add(b2);
        Panel.add(b3);

        Panel.add(imagePos);
        this.add(Panel);
        this.setResizable(false);
        this.setVisible(true);


    }
    @Override
    public void actionPerformed(ActionEvent e) {
        Object obj = e.getSource();
        if(obj == b2){             //清空     

            textName.setText("");
            textPassword1.setText("");
            textPassword2.setText("");
        }   
        if(obj==b3){               //返回

            new ClientLogin();      
            this.setVisible(false);
        }

        if (obj==b1) {
            Properties userPro=new Properties();
            File file=new File("hfz.properties");
            CatUtil.loadPro(userPro, file);
            String u_name=textName.getText();
            String u_pwd=new String(textPassword1.getPassword());
            String u_pwd_ag=new String(
                    textPassword2.getPassword());
            //判断是否存在
            if (u_name.length()!=0) {
                if (userPro.containsKey(u_name)) {
                     try {
                        throw new Exception("用户名存在");
                    } catch (Exception e1) {
                        e1.printStackTrace();
                    }
                }else{
                    try {
                        isPassword(userPro, file, u_name, u_pwd, u_pwd_ag);
                    } catch (Exception e1) {
                        e1.printStackTrace();
                    }
                }
            }else {
                try {
                    throw new Exception("用户名不能为空");
                } catch (Exception e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
            }
        }

    }

    private void isPassword(Properties userPro,
            File file, String u_name, String u_pwd, String u_pwd_ag) throws Exception {
        if (u_pwd.equals(u_pwd_ag)) {
            if (u_pwd.length() != 0) {
                userPro.setProperty(u_name, u_pwd_ag);
                try {
                    userPro.store(new FileOutputStream(file),
                            "Copyright (c) Boxcode Studio");
                } catch (FileNotFoundException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
                b1.setEnabled(false);
                //返回登陆界面
                ClientLogin frame = new ClientLogin();
                frame.setVisible(true);
                setVisible(false);
            } else {
                throw new Exception("密码为空");
            }
        } else {
            throw new Exception("密码不同");
        }
    }

}

相对应的登录块
这里写图片描述

package hfz.Login.cn;


public class ClientLogin extends JFrame implements ActionListener{
    //窗口
    private JLabel UserName;
    private JLabel UserPwd;
    private JPasswordField txtUserPwd;
     public JTextField txtUserName;
    private JButton Login;
    private JButton Register;
    private JButton Cancel;
    private PrintWriter writer;  
    private BufferedReader reader;
    JLabel imagePos;
    public ClientLogin(){
        this.setTitle("欢迎使用聊天室");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        Font font=new Font("宋体",Font.PLAIN,12);
        //组件
        UserName=new JLabel("用户名:");
        UserName.setFont(font);
        UserPwd=new JLabel("密码:");
        UserPwd.setFont(font);
        txtUserPwd=new JPasswordField();
        txtUserName=new JTextField();

        Icon image = new ImageIcon("image/1.jpg");
        imagePos = new JLabel(image);
        //按钮
        //设置按钮组件
                Login=new JButton("登录");
                Login.setFont(font);
                Login.setBackground(new Color(0,155,0));
                Login.setToolTipText("进入聊天界面  ");
                Login.addActionListener(this);

                Register=new JButton("注册");
                Register.setFont(font);
                Register.setBackground(new Color(0,155,0));
                Register.setToolTipText(" 进入注册界面 ");
                Register.addActionListener(this);

                Cancel=new JButton("取消");
                Cancel.setFont(font);
                Cancel.setBackground(new Color(0,155,0));
                Cancel.setToolTipText(" 清除内容 ") ;
                Cancel.addActionListener(this);



             //添加组件
                JPanel panel=new JPanel();
                getContentPane().add(panel);
                panel.setLayout(null);
                UserName.setBounds(new Rectangle(40, 20, 60, 20));//点击会出现矩形框
                txtUserName.setBounds(new Rectangle(100, 20, 180, 20));
                UserPwd.setBounds(new Rectangle(40, 60, 60, 20));
                txtUserPwd.setBounds(new Rectangle(100, 60, 180, 20));

                Login.setBounds(new Rectangle(40,100,60,20));
                Register.setBounds(new Rectangle(130,100,60,20));
                Cancel.setBounds(new Rectangle(220,100,60,20));

                imagePos.setBounds(new Rectangle(0,0,320,160));               

                //把各组件加到框架窗口中
                panel.add(UserName);
                panel.add(UserPwd);
                panel.add(txtUserName);
                panel.add(txtUserPwd);
                panel.add(Login);
                panel.add(Register);
                panel.add(Cancel);
                panel.add(imagePos);
           setResizable(false);
           setSize(320,160);

           Dimension us = this.getSize();
            //获取屏幕的尺寸
            Dimension them = Toolkit.getDefaultToolkit().getScreenSize();
            int newX = (them.width - us.width) / 2 ;
            int newY = (them.height - us.height) / 2 ;      
            this.setLocation(newX,newY);
            setVisible(true);




    }
    //监听
    @Override
    public void actionPerformed(ActionEvent even){

        JButton obj=(JButton)even.getSource();

        if(obj==Cancel){               //取消

            txtUserName.setText(null);
            txtUserPwd.setText(null);
            dispose();
        }
        else if (obj==Login){          //提交

            String n=txtUserName.getText();
            String p=String.valueOf(txtUserPwd.getPassword());

            if(n.length()==0&&p.length()!=0){
                JOptionPane.showMessageDialog(this,"您没有输入姓名","提示!",JOptionPane.CANCEL_OPTION);
                return;
            }
            else if (n.length()!=0&&p.length()==0){
                JOptionPane.showMessageDialog(this,"您没有输入密码","提示!",JOptionPane.CANCEL_OPTION);
                return;
            }
            else if (n.length()==0&&p.length()==0){
                JOptionPane.showMessageDialog(this,"您没有输入姓名和密码","提示!",JOptionPane.CANCEL_OPTION);
                return;
            }

            //调用用户登陆方法
            Properties userPro = new Properties();
            File file = new File("hfz.properties");
            CatUtil.loadPro(userPro, file);
            String u_nameString=txtUserName.getText();
            //System.out.println(nameString);
            if (file.length()!=0) {
                if (userPro.containsKey(u_nameString)) {
                    String u_pwd=new String(
                            txtUserPwd.getPassword());
                    if (u_pwd.equals(userPro.getProperty(u_nameString))) {

                        Login.setEnabled(false);
                        new Client(u_nameString);// 显示聊天界面
                        this.setVisible(false);
                    }else {
                        JOptionPane.showMessageDialog(null,"密码错误");
                        //重置
                        txtUserPwd.setText("");
                        txtUserName.requestFocus();
                    }       
                }else {
                    JOptionPane.showMessageDialog(null,"昵称不存在");
                    txtUserName.setText("");
                    txtUserPwd.setText("");
                    txtUserName.requestFocus();
                }
            }else {
                JOptionPane.showMessageDialog(null,"昵称不存在");
                txtUserName.setText("");
                txtUserPwd.setText("");
                txtUserName.requestFocus();
            }

        }                      
        else if (obj==Register){       //注册

            setVisible(false);
            new hfz.Register.cn.Register();
        } 
    }


}

客户端

package hfz.Clint.cn;



public class Client{  

    private JFrame frame;  
    private JList userList;  
    private JTextArea textArea;  
    private JTextField textField;
    private JButton btn_start;  
    private JButton btn_stop;  
    private JButton btn_send;
    private JButton setFont;   //字体面板
    private JButton bColor;
    private JPanel northPanel;  
    private JPanel southPanel;  
    private JScrollPane rightScroll;  
    private JScrollPane leftScroll;  
    private JSplitPane centerSplit;  

    private DefaultListModel 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 void send() {  
        if (!isConnected) {  
            JOptionPane.showMessageDialog(frame, "还没有连接服务器,无法发送消息!", "错误",  
                    JOptionPane.ERROR_MESSAGE);  
            return;  
        }  
        String message = textField.getText().trim();  
        if (message == null || message.equals("")) {  
            JOptionPane.showMessageDialog(frame, "消息不能为空!", "错误",  
                    JOptionPane.ERROR_MESSAGE);  
            return;  
        }  
        sendMessage(frame.getTitle() + "@" + "ALL" + "@" + message); 

        textField.setText(null);  
    }  

    // 构造方法  
    public Client(final String username) {  

        Font f = new Font("宋体",Font.PLAIN,12);
        textArea = new JTextArea();  
        textArea.setEditable(false);  
        textArea.setForeground(Color.red);  
        textField = new JTextField();   
        btn_start = new JButton("连接"); 
        btn_stop = new JButton("断开");  
        btn_send = new JButton("发送"); 
        setFont=new JButton("文字大小");
        setFont.setToolTipText("☆点击选择字体☆");
        setFont.addActionListener(new FontSet());
        bColor=new JButton("字体颜色");
        bColor.setToolTipText("☆选择颜色☆");
        bColor.addActionListener(new setColor());
        listModel = new DefaultListModel();  
        userList = new JList(listModel);  

        northPanel = new JPanel();  
        northPanel.setLayout(new GridLayout(1, 7));  
        northPanel.add(new JLabel("端口:8888"));  
        northPanel.add(new JLabel("服务器IP:localhost"));   
        northPanel.add(new JLabel("昵称:"+username));  
        northPanel.add(btn_start);  
        northPanel.add(btn_stop);  
        northPanel.setBorder(new TitledBorder("连接信息"));  

        rightScroll = new JScrollPane(textArea);  
        rightScroll.setBorder(new TitledBorder("消息显示区"));  
        leftScroll = new JScrollPane(userList);  
        leftScroll.setBorder(new TitledBorder("在线用户"));  
        southPanel = new JPanel(new BorderLayout());
        southPanel.add(setFont,"North");
        southPanel.add(bColor,"Center");
        southPanel.add(textField,"South");  
        southPanel.add(btn_send, "East");  
        southPanel.setBorder(new TitledBorder("写消息"));  

        centerSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftScroll,  
                rightScroll);  
        centerSplit.setDividerLocation(100);  


        frame = new JFrame("破产版聊天器");   
        // 更改JFrame的图标:                
        frame.setLayout(new BorderLayout());
        frame.add(northPanel, "North");  
        frame.add(centerSplit, "Center");  
        frame.add(southPanel, "South");
        frame.setSize(600, 400);  
        int screen_width = Toolkit.getDefaultToolkit().getScreenSize().width;  
        int screen_height = Toolkit.getDefaultToolkit().getScreenSize().height;  
        frame.setLocation((screen_width - frame.getWidth()) / 2,  
                (screen_height - frame.getHeight()) / 2);  
        frame.setVisible(true);  



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

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

         // 单击连接按钮时事件  
        btn_start.addActionListener(new ActionListener() {  
            public void actionPerformed(ActionEvent e) {  

                String name=username;
                    boolean flag = connectServer(name);  
                    if (flag == false) {  
                        try {
                            throw new Exception("与服务器连接失败!");
                        } catch (Exception e1) {
                            // TODO Auto-generated catch block
                            e1.printStackTrace();
                        }  
                    }  
                    frame.setTitle(name); 
                    JOptionPane.showMessageDialog(frame, "成功连接!");                

                } 

        });  

        // 单击断开按钮时事件  
        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);  
                }  
            }  
        });  

        // 关闭窗口时事件  
        frame.addWindowListener(new WindowAdapter() {  
            public void windowClosing(WindowEvent e) {  
                if (isConnected) {  
                    closeConnection();// 关闭连接  
                }  
                System.exit(0);// 退出程序  
            }  
        });  
    }  

    //颜色
    class setColor implements ActionListener{   
        public void actionPerformed(ActionEvent e){     
            Object obj = e.getSource(); 
            if(obj==(JButton)bColor){   
                Color ch = JColorChooser.showDialog(null,"Swing颜色选取器",getForeground());
                if(ch != null){ 
                    textArea.setForeground(ch); 
                    bColor.setBackground(ch);
                }
            }   
        }

        private Color getForeground() {
            // TODO Auto-generated method stub
            return null;
        }   
    }
    //字体
    class FontSet implements ActionListener{
        public void actionPerformed(ActionEvent e){
            Object obj = e.getSource();
            if(obj== (JButton)setFont)
                setFont();   //调用设置字体方法
        }
    }
    public void setFont(){

        FontChooser fChooser = new FontChooser(frame);
        fChooser.setVisible(true);
        Font myNewFont = fChooser.getSelectedFont();

        textArea.setFont(myNewFont);
        fChooser.dispose();
    }   







    /**  
     * 连接服务器  
     *   
     * @param port  
     * @param hostIp  
     * @param u_nameString2  
     */ 

    public boolean connectServer(String name) {  
        // 连接服务器  
        try {  
            socket = new Socket("localhost",8888);// 根据端口号和服务器ip建立连接  
            writer = new PrintWriter(socket.getOutputStream());  
            reader = new BufferedReader(new InputStreamReader(socket  
                    .getInputStream())); 

            // 发送客户端用户基本信息(用户名和ip地址)  
            sendMessage(name);  
            // 开启接收消息的线程  
            messageThread = new MessageThread(reader, textArea);  
            messageThread.start();  
            isConnected = true;// 已经连接上了  
            return true;  
        } catch (Exception e) {  
            textArea.append("连接失败"+"\r\n");  
            isConnected = false;// 未连接上  
            return false;  
        }  
    }  

    /**  
     * 发送消息  
     *   
     * @param message  
     */  
    public void sendMessage(String message) {  
        writer.println(message);            
        writer.flush();  
    }  

    /**  
     * 客户端主动关闭连接  
     */  
    @SuppressWarnings("deprecation")  
    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 textArea;  

        // 接收消息线程的构造方法  
        public MessageThread(BufferedReader reader, JTextArea textArea) {  
            this.reader = reader;  
            this.textArea = textArea;  
        }  

        // 被动的关闭连接  
        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"))// 服务器已关闭命令  
                    {  
                        textArea.append("服务器已关闭!\r\n");  
                        closeCon();// 被动的关闭连接  
                        return;// 结束线程  
                    } else if (command.equals("ADD")) {// 有用户上线更新在线列表  
                        String username = "";  
                        //String userIp = "";  
                        if ((username = stringTokenizer.nextToken()) != null) {  
                            User user = new User(username);  
                            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);  
                            onLineUsers.put(username, user);  
                            listModel.addElement(username);  
                        }  
                    } else if (command.equals("MAX")) {// 人数已达上限  
                        textArea.append(stringTokenizer.nextToken()  
                                + stringTokenizer.nextToken() + "\r\n");  
                        closeCon();// 被动的关闭连接  
                        JOptionPane.showMessageDialog(frame, "服务器缓冲区已满!", "错误",  
                                JOptionPane.ERROR_MESSAGE);  
                        return;// 结束线程  
                    } else {// 普通消息  
                        textArea.append(message + "\r\n");  
                    }  
                } catch (IOException e) {  
                    e.printStackTrace();  
                } catch (Exception e) {  
                    e.printStackTrace();  
                }  
            }  
        }  
    }
}  

服务端

package hfz.Server.cn;



public class Server {  

    private JFrame frame;  
    private JTextArea contentArea;   
    private JTextField txt_max;  
    //private JTextField txt_port;  
    private JButton btn_start;  
    private JButton btn_stop;   
    private JPanel northPanel;  
    private JScrollPane rightPanel;  
    private JScrollPane leftPanel;  
    private JSplitPane centerSplit;  
    private JList userList;  
    private DefaultListModel listModel;  

    private ServerSocket serverSocket;  
    private ServerThread serverThread;  
    private ArrayList<ClientThread> clients;  

    private boolean isStart = false;  

    // 主方法,程序执行入口  
    public static void main(String[] args) {  
        new Server();  
    }  



    // 构造放法  
    public Server() {  
        frame = new JFrame("终端显示");  
        contentArea = new JTextArea();  
        contentArea.setEditable(false);  
        contentArea.setForeground(Color.blue);  
        txt_max = new JTextField("10");  
        //txt_port = new JTextField("8888");  
        btn_start = new JButton("启动");  
        btn_stop = new JButton("停止");   
        btn_stop.setEnabled(false);  
        listModel = new DefaultListModel();  
        userList = new JList(listModel);  

        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, 6));  
        northPanel.add(new JLabel("人数上限"));  
        northPanel.add(txt_max);  
        northPanel.add(new JLabel("端口:8888"));  
        //northPanel.add(txt_port);  
        northPanel.add(btn_start);  
        northPanel.add(btn_stop);  
        northPanel.setBorder(new TitledBorder("配置信息"));  

        frame.setLayout(new BorderLayout());  
        frame.add(northPanel, "North");  
        frame.add(centerSplit, "Center");  
        frame.setSize(400, 200);  
        //frame.setSize(Toolkit.getDefaultToolkit().getScreenSize());//设置全屏  
        int screen_width = Toolkit.getDefaultToolkit().getScreenSize().width;  
        int screen_height = Toolkit.getDefaultToolkit().getScreenSize().height;  
        frame.setLocation((screen_width - frame.getWidth()) / 2,  
                (screen_height - frame.getHeight()) / 2);  
        frame.setVisible(true);  

        // 关闭窗口时事件  
        frame.addWindowListener(new WindowAdapter() {  
            public void windowClosing(WindowEvent e) {  
                if (isStart) {  
                    closeServer();// 关闭服务器  
                }  
                System.exit(0);// 退出程序  
            }  
        });  


        // 单击启动服务器按钮时事件  
        btn_start.addActionListener(new ActionListener() {  
            public void actionPerformed(ActionEvent e) {  
                if (isStart) {  
                    JOptionPane.showMessageDialog(frame, "服务器已处于启动状态,不要重复启动!",  
                            "错误", JOptionPane.ERROR_MESSAGE);  
                    return;  
                }  
                int max;  
                //int port; 

                try {  
                    try {  
                        max = Integer.parseInt(txt_max.getText());  
                    } catch (Exception e1) {  
                        throw new Exception("人数上限为正整数!");  
                    }  
                    if (max <= 0) {  
                        throw new Exception("人数上限为正整数!");  
                    } 

                    serverStart(max);  
                    contentArea.append("服务器已成功启动!人数上限:" + max + "\r\n");  
                    JOptionPane.showMessageDialog(frame, "服务器成功启动!");  
                    btn_start.setEnabled(false);  
                    txt_max.setEnabled(false);  
                   // txt_port.setEnabled(false);  
                    btn_stop.setEnabled(true);  
                } catch (Exception exc) {  
                    JOptionPane.showMessageDialog(frame, exc.getMessage(),  
                            "错误", JOptionPane.ERROR_MESSAGE);  
                }  
            }  
        });  

        // 单击停止服务器按钮时事件  
        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);  
                }  
            }  
        });  
    }  

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

    // 关闭服务器  
    @SuppressWarnings("deprecation")  
    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();  
                    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());  
                        // 反馈连接成功信息  
                        w.println("MAX@服务器:对不起," + user.getName()  
                                +  ",服务器在线人数已达上限,请稍后尝试连接!");  
                        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()  
                            +  "上线!\r\n");  
                } catch (IOException 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());  
                // 反馈连接成功信息  
                writer.println(user.getName() +  "与服务器连接成功!");  
                writer.flush();  
                // 反馈当前在线用户信息  
                if (clients.size() > 0) {  
                    String temp = "";  
                    for (int i = clients.size() - 1; i >= 0; i--) {  
                        temp += (clients.get(i).getUser().getName() + "/" )  
                                + "@";  
                    }  
                    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());  
                    clients.get(i).getWriter().flush();     
                }  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
        }  

        @SuppressWarnings("deprecation")  
        public void run() {// 不断接收客户端的消息,进行处理。  
            String message = null;  
            while (true) {  
                try {  
                    message = reader.readLine();// 接收客户端消息  
                    if (message.equals("CLOSE"))// 下线命令  
                    {  
                        contentArea.append(this.getUser().getName()  
                                +  "下线!\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();  
            message = source + "说:" + content;  
            contentArea.append(message + "\r\n");  
            if (owner.equals("ALL")) {// 群发  
                for (int i = clients.size() - 1; i >= 0; i--) {  
                    clients.get(i).getWriter().println(message);  
                    clients.get(i).getWriter().flush();  
                }  
            }  
        }  
    }  
}  

主类:先开启服务,再登录连接

package hfz.main.cn;

import hfz.Login.cn.ClientLogin;

public class Test {

    public static void main(String[] args) {
        new ClientLogin().txtUserName.getText();
    }

}

这里写图片描述

代码资源地址补上,也感谢支持:
javaSocket简单聊天室

  • 7
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值