java socket简易聊天室

来源:互联网 发布:广州小孩学编程 编辑:程序博客网 时间:2024/05/08 08:38

对学完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();    }}

这里写图片描述

PS:自己也是新人,当时学这个知识点,没打算停留,啥的界面,排布都不怎么好看,当然也感谢其他朋友文档参考(时间有点久,不记得地址了,抱歉),当然,做的还是有自己风味,也希望自己越学越好吧。

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

0 0
原创粉丝点击