zoukankan      html  css  js  c++  java
  • java学习之即时通信项目实战

     项目总结:这次项目主要是根据视频来的,结果跟到一半感觉跟不上,慢慢自己有了自己的想法,决定自己先不看学习视频,自己先试着写。

      总结写前面,算是写的第一个项目吧。项目中遇到几点问题,首先Scoket对象创建后,服务器端和客户端不能同时创建输入流,否者会引起堵塞。

      然后,读入流应该重新创建个线程做等待写入服务,因为读入流会引起当前线程进入阻塞状态。

         还有一个用户线程对应一个服务线程,不是多个用户线程对应一个服务线程。

         对对象的操作应该由那个对象本身提供操作方法,比如操作UI界面的变化应该由界面本身提拱。

      最后最重要的是写代码之前应该先画个流程图,写代码时参数乱传的,哪里需要就调参数过来。导致思路不清.

    首先是需求分析:

      本次项目是模拟及时通信中最基本的功能,类似QQ的应用.

      项目分为:

       (1)服务器端:

        服务器端主要负责用户管理,消息转发功能

       (2) 客户端:

        客户端主要负责用户间的消息发送

    详细设计

    服务器端

      1、登录服务器后,进行客户端的监听,如有客户端连接,启动用户服务线程,与客户端进行交互。

      2、如客户端向所有人发送消息,服务器将向所有在线用户广播该消息。

          3、如客户端向指定人发送消息,服务器将查找接收人用户线程后转发消息。

          4、用户登录后,向所有人更新用户列表。

    客户端:

    1、用户登录功能。

    2、登录后用户可以看到在线用户列表

    3 、向指定人发送消息

    4、向所有人发送消息

    代码的实现

    首先,先构建界面图形出来

    上面左边是用户界面(服务器界面和用户界面一样),右边是登录界面

    由于全用手写代码比较麻烦,我用了可视化UI插件;

    画出来如下图

    界面做出来了,然后构建对象模型,

    这里主要需要信息对象,和用户对象;

    信息对象又分,登录信息,发送信息和退出信息。这里我把登录信息单独用一个对象构建,因为保存了帐号密码,以后好增加登录验证功能。

    然后就是逻辑功能的实现了。

    这里我发现看似简单的功能,实现起来还是有点麻烦的。学会了一点就是要模块化。不然自己很容易搞迷糊。

    直接上代码:

    客户端代码

      1 package com.gh.Client;
      2 
      3 import java.awt.Toolkit;
      4 
      5 public class ClientFrame {
      6 
      7     private JFrame Clientframe;
      8     private JTextField textField;
      9     private String username;
     10     private JTextArea textArea = null;
     11     private JList<String> list = null;
     12     private DefaultListModel<String> model = null;
     13     private UserService us;
     14 
     15     // 初始化用户列表
     16     public void InitUserList() {
     17         model = new DefaultListModel<String>();
     18         model.addElement("所有人");
     19         list.setModel(model);
     20     }
     21 
     22     // 添加用户到在线列表
     23     public void AddUserToList(String username) {
     24         // 拆了东墙补西墙。。。之前添加的要全删了,再添加一次
     25         model.removeAllElements();
     26         model.addElement("所有人");
     27         String[] str = username.split(",");
     28         for (String s : str) {
     29             model.addElement(s);
     30         }
     31         //list.setModel(model);
     32     }
     33 
     34     public void updateText(String text) {
     35         StringBuffer sb = new StringBuffer();
     36         sb.append(textArea.getText()).append(DateUtil.getTime() + "
    ").append(text).append("
    ");
     37         textArea.setText(sb.toString());
     38     }
     39     public void DelUser(String username){
     40         model.removeElement(username);
     41     }
     42 
     43     /**
     44      * Create the application.
     45      */
     46     public ClientFrame(String username,UserService us) {
     47         this.username = username;
     48         this.us=us;
     49         initialize();
     50         // 初始化用户列表
     51         InitUserList();
     52     }
     53 
     54     /**
     55      * Initialize the contents of the frame.
     56      */
     57     private void initialize() {
     58         Clientframe = new JFrame();
     59         Clientframe.addWindowListener(new WindowAdapter() {
     60             @Override
     61             public void windowClosing(WindowEvent e) {
     62                 Info info=new Info();
     63                 info.setFromUser(username);
     64                 info.setInfoType(EnumInfoType.EXIT);
     65                 us.send(info);
     66                 us.setFlag(false);
     67                 Clientframe.dispose();
     68             }
     69         });
     70         Clientframe.setVisible(true);
     71         Clientframe
     72                 .setIconImage(Toolkit.getDefaultToolkit().getImage(ClientFrame.class.getResource("/com/gh/res/1.png")));
     73         Clientframe.setTitle("u804Au804A-u5BA2u6237u7AEF");
     74         Toolkit tk = Toolkit.getDefaultToolkit();
     75         Dimension d = tk.getScreenSize();
     76         int x = (int) (d.getWidth() - 534) / 2;
     77         int y = (int) (d.getHeight() - 383) / 2;
     78         Clientframe.setBounds(x, y, 534, 383);
     79         Clientframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     80         Clientframe.getContentPane().setLayout(new BorderLayout(0, 0));
     81 
     82         JLabel label = new JLabel("当前用户是:" + username);
     83         Clientframe.getContentPane().add(label, BorderLayout.NORTH);
     84 
     85         JPanel jpanel = new JPanel();
     86         Clientframe.getContentPane().add(jpanel, BorderLayout.EAST);
     87         jpanel.setLayout(new BorderLayout(0, 0));
     88 
     89         JLabel lblNewLabel = new JLabel("--u5728u7EBFu7528u6237u5217u8868--");
     90         jpanel.add(lblNewLabel, BorderLayout.NORTH);
     91 
     92         list = new JList<String>();
     93         jpanel.add(list, BorderLayout.CENTER);
     94 
     95         JScrollPane scrollPane = new JScrollPane();
     96         Clientframe.getContentPane().add(scrollPane, BorderLayout.CENTER);
     97 
     98         textArea = new JTextArea();
     99         scrollPane.setViewportView(textArea);
    100 
    101         JPanel panel = new JPanel();
    102         Clientframe.getContentPane().add(panel, BorderLayout.SOUTH);
    103         panel.setLayout(new BorderLayout(0, 0));
    104 
    105         JLabel lblNewLabel_1 = new JLabel("u8BF7u8F93u5165uFF1A");
    106         panel.add(lblNewLabel_1, BorderLayout.WEST);
    107 
    108         textField = new JTextField();
    109         panel.add(textField, BorderLayout.CENTER);
    110         textField.setColumns(10);
    111 
    112         JButton button = new JButton("u53D1u9001");
    113         button.addActionListener(new ActionListener() {
    114             public void actionPerformed(ActionEvent e) {
    115                 // 获取发送信息
    116                 String sendContent = textField.getText().trim();
    117                 // 获取发送对象
    118                 Info info = new Info();
    119                 info.setFromUser(username);
    120                 info.setToUser((String) list.getSelectedValue());
    121                 info.setContent(sendContent);
    122                 info.setInfoType(EnumInfoType.SEND_INFO);
    123                 System.out.println(info.getToUser());
    124                 // 首先判断发送对象是否为空
    125                 if ("".equals(info.getToUser()) || info.getToUser() == null) {
    126                     JOptionPane.showMessageDialog(Clientframe, "请选择发送对象");
    127                     return;
    128                 } else if (info.getToUser().equals(username)) {
    129                     JOptionPane.showMessageDialog(Clientframe, "不能对自己发送");
    130                     return;
    131                 } else if (info.getContent().equals("") || info.getContent() == null) {
    132                     JOptionPane.showMessageDialog(Clientframe, "内容不能为空");
    133                     return;
    134                 } else
    135                     us.send(info);
    136                 textField.setText("");
    137             }
    138         });
    139         panel.add(button, BorderLayout.EAST);
    140     }
    141 
    142 }
    ClientFrame
      1 package com.gh.Client;
      2 
      3 import java.awt.Dimension;
      4 
      5 @SuppressWarnings("unused")
      6 public class LoginFrame {
      7 
      8     private JFrame frame;
      9     private JTextField id;
     10     private JPasswordField pwd;
     11 
     12 
     13     /**
     14      * Launch the application.
     15      */
     16     public static void main(String[] args) {
     17         EventQueue.invokeLater(new Runnable() {
     18             public void run() {
     19                 try {
     20                     LoginFrame window = new LoginFrame();
     21                     window.frame.setVisible(true);
     22                     UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
     23                 } catch (Exception e) {
     24                     e.printStackTrace();
     25                 }
     26             }
     27         });
     28     }
     29 
     30     /**
     31      * Create the application.
     32      */
     33     public LoginFrame() {
     34         initialize();
     35     }
     36 
     37     /**
     38      * Initialize the contents of the frame.
     39      */
     40     private void initialize() {
     41         frame =  new JFrame();
     42         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     43         frame.setVisible(true);
     44         frame.setIconImage(Toolkit.getDefaultToolkit().getImage(LoginFrame.class.getResource("/com/gh/res/1.png")));
     45         Toolkit tk=Toolkit.getDefaultToolkit();
     46         Dimension d=tk.getScreenSize();
     47         int x=(int)(d.getWidth()-379)/2;
     48         int y=(int)(d.getHeight()-171)/2;
     49         frame.setResizable(false);
     50         frame.setTitle("u767Bu5F55");
     51         frame.setBounds(x, y, 379, 171);
     52         frame.getContentPane().setLayout(new GridLayout(3, 1, 20, 5));
     53         
     54         JPanel panel = new JPanel();
     55         frame.getContentPane().add(panel);
     56         FlowLayout fl_panel = new FlowLayout(FlowLayout.CENTER, 5, 10);
     57         fl_panel.setAlignOnBaseline(true);
     58         panel.setLayout(fl_panel);
     59         
     60         JLabel label = new JLabel("u7528u6237u5E10u53F7uFF1A");
     61         label.setFont(new Font("微软雅黑", Font.PLAIN, 15));
     62         panel.add(label);
     63         
     64         id = new JTextField();
     65         panel.add(id);
     66         id.setColumns(15);
     67         
     68         
     69         JPanel panel_1 = new JPanel();
     70         FlowLayout flowLayout = (FlowLayout) panel_1.getLayout();
     71         flowLayout.setAlignOnBaseline(true);
     72         flowLayout.setVgap(10);
     73         frame.getContentPane().add(panel_1);
     74         
     75         JLabel label_1 = new JLabel("u7528u6237u5BC6u7801uFF1A");
     76         label_1.setFont(new Font("微软雅黑", Font.PLAIN, 15));
     77         panel_1.add(label_1);
     78         
     79         pwd = new JPasswordField();
     80         pwd.setColumns(15);
     81         panel_1.add(pwd);
     82         
     83         JPanel panel_2 = new JPanel();
     84         FlowLayout flowLayout_1 = (FlowLayout) panel_2.getLayout();
     85         flowLayout_1.setVgap(6);
     86         frame.getContentPane().add(panel_2);
     87         
     88         JButton button = new JButton("u767Bu5F55");
     89         button.addActionListener(new ActionListener() {
     90             public void actionPerformed(ActionEvent arg0) {
     91                 String username=id.getText().trim();
     92                 String password=new String(pwd.getPassword());
     93                 if("".equals(username)||username==null||"".equals(password)||password==null){
     94                     JOptionPane.showMessageDialog(frame, "用户名和密码不能为空");
     95                     return;
     96                 }
     97                 new UserService().login(username, password,frame);
     98             }
     99         });
    100         button.setFont(new Font("微软雅黑", Font.PLAIN, 15));
    101         panel_2.add(button);
    102         
    103         JButton button_1 = new JButton("u9000u51FA");
    104         button_1.addActionListener(new ActionListener() {
    105             public void actionPerformed(ActionEvent e) {
    106                 int v=JOptionPane.showConfirmDialog(frame, "真的要退出吗", "退出", JOptionPane.YES_NO_OPTION);
    107                 if(v==JOptionPane.YES_OPTION)System.exit(0);
    108             }
    109         });
    110         button_1.setFont(new Font("微软雅黑", Font.PLAIN, 15));
    111         panel_2.add(button_1);
    112     }
    113 
    114     
    115 }
    LoginFrame
     1 package com.gh.Client;
     2 
     3 import java.io.IOException;
     4 import java.io.ObjectInputStream;
     5 import java.io.ObjectOutputStream;
     6 import java.net.Socket;
     7 
     8 import javax.swing.JFrame;
     9 import javax.swing.JOptionPane;
    10 
    11 import com.gh.model.Info;
    12 import com.gh.model.LoginInfo;
    13 
    14 public class UserService {
    15     private LoginInfo logininfo = null;
    16     private ClientFrame clientframe = null;
    17     private boolean flag = true;
    18     private Info getInfo = null;
    19     public boolean isFlag() {
    20         return flag;
    21     }
    22     public void setFlag(boolean flag) {
    23         this.flag = flag;
    24     }
    25     private ObjectOutputStream bw;
    26     private ObjectInputStream br;
    27     public void login(final String username, final String password, final JFrame frame) {
    28         //接收消息线程
    29         Thread t=new Thread(new Runnable() {
    30             @Override
    31             public void run() {
    32                 try {
    33                     Socket sk = new Socket("192.168.1.102", 8000);
    34                     //这里被堵了好久,必须要先创建bw再创建br,因为scoket不许客户端和服务端同时创建输入流否者会堵塞Scoket通道
    35                     bw =new ObjectOutputStream(sk.getOutputStream());
    36                     br = new ObjectInputStream(sk.getInputStream());
    37                     logininfo = new LoginInfo(username, password);
    38                     bw.writeObject(logininfo);//向服务器发送登录信息
    39                     bw.flush();
    40                     //从服务接收登录信息
    41                     LoginInfo objflag = (LoginInfo) br.readObject();
    42                     if (objflag.isFlag()) {// 如果可以登录
    43                         // 创建聊天界面
    44                         clientframe = new ClientFrame(logininfo.getName(),UserService.this);
    45                         // 聊天界面显示欢迎信息
    46                         clientframe.updateText("服务器:欢迎登录!");
    47                         frame.dispose();
    48                         // 等待接收消息 
    49                         while (isFlag()) {
    50                             getInfo = new Info();
    51                             getInfo = (Info) br.readObject();
    52                             switch (getInfo.getInfoType()) {
    53                             case SEND_INFO:
    54                                 clientframe.updateText("用户:"+getInfo.getFromUser()+"说:"+getInfo.getContent());
    55                                 break;
    56                             case ADD_USER:
    57                                 clientframe.AddUserToList(getInfo.getContent());
    58                                 break;
    59                             case EXIT:
    60                                 clientframe.DelUser(getInfo.getFromUser());
    61                                 clientframe.updateText("服务器:用户"+getInfo.getFromUser()+"下线了");
    62                                 break;
    63                             default:
    64                                 break;
    65                             }
    66 
    67                         }
    68                     } else {
    69                         JOptionPane.showMessageDialog(frame, "用户名或密码错误");
    70                     }
    71                 } catch (Exception e) {
    72                     JOptionPane.showMessageDialog(frame, "服务器连接异常");
    73                      //e.printStackTrace();
    74                 }
    75             }
    76         });
    77         t.start();
    78     }
    79     //发送消息线程
    80     public void send(Info info){
    81         try {
    82             bw.writeObject(info);
    83             bw.flush();
    84         } catch (IOException e) {
    85             e.printStackTrace();
    86         }
    87     }
    88 }
    UserService

    服务端代码

      1 package com.gh.Sever;
      2 
      3 import java.awt.EventQueue;
      4 
      5 public class ServerFrame {
      6 
      7     private JFrame Severframe;
      8     private JTextField textField;
      9     private JTextArea textArea = null;
     10     private DefaultListModel<String> model=null;
     11     private JList<String> list=null;
     12     /**
     13      * Launch the application.
     14      */
     15     public static void main(String[] args) {
     16         EventQueue.invokeLater(new Runnable() {
     17             public void run() {
     18                 try {
     19                     ServerFrame window = new ServerFrame();
     20                     window.Severframe.setVisible(true);
     21                     // 设置UI风格为系统默认的风格
     22                     //UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
     23                 } catch (Exception e) {
     24                     e.printStackTrace();
     25                 }
     26             }
     27         });
     28 
     29     }
     30     //初始化用户列表
     31     public void InitUserList(){
     32         model=new DefaultListModel<String>();
     33         model.addElement("所有人");
     34         list.setModel(model);
     35     }
     36     //添加用户到在线列表
     37     public void AddUserToList(String username){
     38         model.addElement(username);
     39         list.setModel(model);
     40     }
     41     public void updateText(String text) {
     42         StringBuffer sb = new StringBuffer();
     43         sb.append(textArea.getText()).append("
    ").append(DateUtil.getTime()+"--")
     44             .append(text);
     45         textArea.setText(sb.toString());
     46     }
     47     public void DelUser(String username){
     48         model.removeElement(username);
     49     }
     50     /**
     51      * Create the application.
     52      */
     53     public ServerFrame() {
     54         initialize();
     55         // 启动服务
     56         startSever();
     57         //初始化用户列表
     58         InitUserList();
     59     }
     60 
     61     private void startSever() {
     62         textArea.setText("服务器已经启动,正在监听8000端口...");
     63         new Thread(new Runnable() {
     64             @Override
     65             public void run() {
     66                 new ServerService(ServerFrame.this).startSever();
     67             }
     68         }).start();
     69     }
     70 
     71     /**
     72      * Initialize the contents of the frame.
     73      */
     74     private void initialize() {
     75         Severframe = new JFrame();
     76         Severframe
     77                 .setIconImage(Toolkit.getDefaultToolkit().getImage(ServerFrame.class.getResource("/com/gh/res/1.png")));
     78         Severframe.setTitle("u804Au804A-u670Du52A1u7AEF");
     79         Toolkit tk = Toolkit.getDefaultToolkit();
     80         Dimension d = tk.getScreenSize();
     81         int x = (int) (d.getWidth() - 534) / 2;
     82         int y = (int) (d.getHeight() - 383) / 2;
     83         Severframe.setBounds(x, y, 534, 383);
     84         Severframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     85         Severframe.getContentPane().setLayout(new BorderLayout(0, 0));
     86 
     87         JLabel label = new JLabel("u670Du52A1u5668u7AEF");
     88         Severframe.getContentPane().add(label, BorderLayout.NORTH);
     89 
     90         JPanel jpanel = new JPanel();
     91         Severframe.getContentPane().add(jpanel, BorderLayout.EAST);
     92         jpanel.setLayout(new BorderLayout(0, 0));
     93 
     94         JLabel lblNewLabel = new JLabel("--u5728u7EBFu7528u6237u5217u8868--");
     95         jpanel.add(lblNewLabel, BorderLayout.NORTH);
     96 
     97         list = new JList<String>();
     98         jpanel.add(list, BorderLayout.CENTER);
     99 
    100         JScrollPane scrollPane = new JScrollPane();
    101         Severframe.getContentPane().add(scrollPane, BorderLayout.CENTER);
    102 
    103         textArea = new JTextArea();
    104         scrollPane.setViewportView(textArea);
    105 
    106         JPanel panel = new JPanel();
    107         Severframe.getContentPane().add(panel, BorderLayout.SOUTH);
    108         panel.setLayout(new BorderLayout(0, 0));
    109 
    110         JLabel lblNewLabel_1 = new JLabel("u8BF7u8F93u5165uFF1A");
    111         panel.add(lblNewLabel_1, BorderLayout.WEST);
    112 
    113         textField = new JTextField();
    114         panel.add(textField, BorderLayout.CENTER);
    115         textField.setColumns(10);
    116 
    117         JButton button = new JButton("u53D1u9001");
    118         panel.add(button, BorderLayout.EAST);
    119     }
    120 
    121 }
    ServerFrame
      1 package com.gh.Sever;
      2 
      3 import java.io.IOException;
      4 import java.io.ObjectInputStream;
      5 import java.io.ObjectOutputStream;
      6 import java.net.ServerSocket;
      7 import java.net.Socket;
      8 import java.util.Vector;
      9 import java.util.concurrent.ExecutorService;
     10 import java.util.concurrent.Executors;
     11 
     12 import com.gh.model.Info;
     13 import com.gh.model.LoginInfo;
     14 import com.gh.util.EnumInfoType;
     15 
     16 /**
     17  * 服务器客户端监听
     18  * 
     19  * @author ganhang
     20  */
     21 public class ServerService {
     22     private Info currInfo = null;
     23     private ServerFrame serFrame;
     24     private boolean flag;
     25     private UserServerThread ust;
     26     ExecutorService es = Executors.newScheduledThreadPool(1);
     27     // 保存所有在线用户服务线程
     28     private Vector<UserServerThread> userThreads;
     29 
     30     public ServerService(ServerFrame serFrame) {
     31         this.serFrame = serFrame;
     32     }
     33 
     34     public void startSever() {
     35         flag = true;
     36         try {
     37             ServerSocket server = new ServerSocket(8000);
     38             userThreads = new Vector<UserServerThread>();
     39             while (flag) {
     40                 Socket client = server.accept();
     41                 System.out.println("Server:有用户连接");
     42                 ObjectInputStream ois = new ObjectInputStream(client.getInputStream());
     43                 ObjectOutputStream oos = new ObjectOutputStream(client.getOutputStream());
     44                 LoginInfo logininfo = (LoginInfo) ois.readObject();// 获取用户帐号密码
     45                 System.out.println(logininfo);
     46                 // 登录验证
     47                 if (UserLogin.islogin(logininfo.getName(), logininfo.getPwd())) {
     48                     logininfo.setFlag(true);
     49                     oos.writeObject(logininfo);// 发送确认登录信息
     50                     oos.flush();
     51                     // 保存当前用户信息
     52                     currInfo = new Info();
     53                     currInfo.setFromUser(logininfo.getName());
     54                     // 在服务器端显示用户登录信息
     55                     serFrame.updateText("用户" + logininfo.getName() + "--已上线!");
     56                     // 创建用户服务线程
     57                     UserServerThread ust = new UserServerThread(currInfo, ois, oos);// 创建用户服务进程
     58                     userThreads.add(ust);// 添加到进程池
     59                     es.execute(ust);// 启动线程
     60                 } else
     61                     oos.writeObject(logininfo);
     62             }
     63         } catch (IOException | ClassNotFoundException e) {
     64             e.printStackTrace();
     65         }
     66     }
     67 
     68     /**
     69      * 用户服务线程
     70      * 
     71      * @author ganhang
     72      */
     73     class UserServerThread implements Runnable {
     74         private Info info = null;
     75         private ObjectOutputStream oos;
     76         private ObjectInputStream ois;
     77 
     78         public UserServerThread(Info info, ObjectInputStream ois, ObjectOutputStream oos) {
     79             this.info = info;
     80             this.oos = oos;
     81             this.ois = ois;
     82         }
     83 
     84         @Override
     85         public void run() {
     86             // 更新服务器的在线用户列表
     87             serFrame.AddUserToList(currInfo.getFromUser());
     88             // 先获得在线用户的列表
     89             StringBuffer sb = new StringBuffer();
     90             for (UserServerThread u : userThreads) {
     91                 sb.append(u.info.getFromUser()).append(",");
     92             }
     93             System.out.println(sb.toString());
     94             // 首先向线程池里每个用户发送一个自己的在线用户列表
     95             for (UserServerThread usts : userThreads) {
     96                 try {
     97                     currInfo.setInfoType(EnumInfoType.ADD_USER);
     98                     currInfo.setContent(sb.toString());
     99                     usts.oos.writeObject(currInfo);// 注意要写那个线程的输出流
    100                     usts.oos.flush();
    101                 } catch (IOException e) {
    102                     e.printStackTrace();
    103                 }
    104             }
    105             // 等待接收用户信息
    106             System.out.println(flag);
    107             new Thread(new Wait(ois, oos)).start();
    108 
    109         }
    110 
    111         public void send(Info sendinfo) throws IOException {
    112             oos.writeObject(sendinfo);
    113             oos.flush();
    114         }
    115     }
    116 
    117     // 接收信息
    118     class Wait implements Runnable {
    119         private ObjectOutputStream oos;
    120         private ObjectInputStream ois;
    121         private boolean wait = true;
    122 
    123         public Wait(ObjectInputStream ois, ObjectOutputStream oos) {
    124             this.oos = oos;
    125             this.ois = ois;
    126         }
    127 
    128         @Override
    129         public void run() {
    130             while (wait) {
    131                 try {
    132                     // 接收信息必须重开线程因为会把当前线程阻塞
    133                     Info info = (Info) ois.readObject();
    134                     System.out.println(Thread.currentThread().getName() + "收到一个send信息");
    135                     System.out.println(info);
    136                     switch (info.getInfoType()) {
    137                     case SEND_INFO:
    138                         if (info.getToUser().equals("所有人")) {
    139                             for (UserServerThread user : userThreads) {
    140                                 //这里容易发错人,注意每个用户都有一个服务线程,哪个用户要接收信息就由它的服务线程去发给它,其他用户的服务线程发不了。
    141                                 if (!info.getFromUser().equals(user.info.getFromUser()))
    142                                     user.send(info);
    143                                 System.out.print(user.info.getFromUser() + "/");
    144                             }
    145                             System.out.println("消息发送名单");
    146                         } else {
    147                             for (UserServerThread user : userThreads) {
    148                                 if (info.getToUser().equals(user.info.getFromUser())) {
    149                                     user.send(info);
    150                                 }
    151                             }
    152                         }
    153                         break;
    154                     case EXIT:
    155                         serFrame.DelUser(info.getFromUser());
    156                         serFrame.updateText("用户" + info.getFromUser() + "下线了");
    157                         for (UserServerThread user : userThreads) {
    158                             if (!info.getFromUser().equals(user.info.getFromUser())) {
    159                                 user.send(info);
    160                             } 
    161                             //这里ust保存的是最后登录的用户的线程因为一直在被覆盖,
    162                             //需要重新写如当前要删的
    163                             else ust = user;
    164                             System.out.print(user.info.getFromUser() + ",");
    165                         }
    166                         System.out.println("退出发送名单");
    167                         // 删除服务器上的该在线用户
    168                         wait = false;
    169                         System.out.println("移除的用户:" + ust.info.getFromUser());
    170                         //这里容易删错用户线程
    171                         userThreads.remove(ust);
    172                         break;
    173                     default:
    174                         break;
    175                     }
    176                 } catch (ClassNotFoundException | IOException e) {
    177                      e.printStackTrace();
    178                 }
    179 
    180             }
    181         }
    182     }
    183 
    184 }
    ServerService
     1 package com.gh.Sever;
     2 /**
     3  * 登录验证,以后加数据库在写
     4  * @author ganhang
     5  */
     6 public class UserLogin {
     7     public static  boolean islogin(String name ,String pwd){
     8         return true;
     9     }
    10 }
    UserLogin

    对象模型

     1 package com.gh.model;
     2 
     3 import java.io.Serializable;
     4 
     5 import com.gh.util.EnumInfoType;
     6 /**
     7  * 消息对象
     8  * @author ganhang
     9  *
    10  */
    11 public class Info implements Serializable{
    12     private String fromUser;//信息来自哪
    13     private String toUser;//发给谁
    14     private String content;//内容
    15     private EnumInfoType infoType;//信息类型
    16     public String getFromUser() {
    17         return fromUser;
    18     }
    19     public void setFromUser(String fromUser) {
    20         this.fromUser = fromUser;
    21     }
    22     public String getToUser() {
    23         return toUser;
    24     }
    25     public void setToUser(String toUser) {
    26         this.toUser = toUser;
    27     }
    28 
    29     public String getContent() {
    30         return content;
    31     }
    32     public void setContent(String content) {
    33         this.content = content;
    34     }
    35     public EnumInfoType getInfoType() {
    36         return infoType;
    37     }
    38     public void setInfoType(EnumInfoType infoType) {
    39         this.infoType = infoType;
    40     }
    41     public Info(String fromUser, String toUser, String sendTime, String content, EnumInfoType infoType) {
    42         super();
    43         this.fromUser = fromUser;
    44         this.toUser = toUser;
    45 
    46         this.content = content;
    47         this.infoType = infoType;
    48     }
    49     @Override
    50     public String toString() {
    51         return "Info [fromUser=" + fromUser + ", toUser=" + toUser  + ", content=" + content
    52                 + ", infoType=" + infoType + "]";
    53     }
    54     public Info() {
    55         super();
    56     }
    57     
    58 }
    Info
     1 package com.gh.model;
     2 
     3 import java.io.Serializable;
     4 
     5 @SuppressWarnings("serial")
     6 public class LoginInfo implements Serializable{
     7     private String name;
     8     private String pwd;
     9     private boolean flag=false;
    10     public String getName() {
    11         return name;
    12     }
    13     public void setName(String name) {
    14         this.name = name;
    15     }
    16     public String getPwd() {
    17         return pwd;
    18     }
    19     public void setPwd(String pwd) {
    20         this.pwd = pwd;
    21     }
    22     public boolean isFlag() {
    23         return flag;
    24     }
    25     public void setFlag(boolean flag) {
    26         this.flag = flag;
    27     }
    28     public LoginInfo(String name, String pwd) {
    29         super();
    30         this.name = name;
    31         this.pwd = pwd;
    32     }
    33     public LoginInfo() {
    34         super();
    35     }
    36     @Override
    37     public String toString() {
    38         return "LoginInfo [name=" + name + ", pwd=" + pwd + ", flag=" + flag + "]";
    39     }
    40     
    41 }
    LoginInfo
     1 package com.gh.model;
     2 /**
     3  * 用户模型
     4  * @author ganhang
     5  * 暂时没用,因为没涉及数据库和一些用户管理功能
     6  */
     7 public class User {
     8     private String name;
     9     private String age;
    10     private String pwd;
    11     private String email;
    12     public String getName() {
    13         return name;
    14     }
    15     public void setName(String name) {
    16         this.name = name;
    17     }
    18     public String getAge() {
    19         return age;
    20     }
    21     public void setAge(String age) {
    22         this.age = age;
    23     }
    24     public String getPwd() {
    25         return pwd;
    26     }
    27     public void setPwd(String pwd) {
    28         this.pwd = pwd;
    29     }
    30     public String getEmail() {
    31         return email;
    32     }
    33     public void setEmail(String email) {
    34         this.email = email;
    35     }
    36     @Override
    37     public String toString() {
    38         return "User [name=" + name + ", age=" + age + ", pwd=" + pwd + ", email=" + email + "]";
    39     }
    40     public User(String name, String age, String pwd, String email) {
    41         super();
    42         this.name = name;
    43         this.age = age;
    44         this.pwd = pwd;
    45         this.email = email;
    46     }
    47     public User() {
    48         super();
    49     }
    50     public User(String name, String pwd) {
    51         super();
    52         this.name = name;
    53         this.pwd = pwd;
    54     }
    55     public User(String name) {
    56         super();
    57         this.name = name;
    58     }
    59     
    60 }
    User

     整个代码:https://github.com/ganhang/My-ChatSystem

  • 相关阅读:
    开学第二周java作业暨动手动脑p1
    开学第一周
    暑假第九周
    暑假第八周
    bzoj4033:[HAOI2015]树上染色
    bzoj4472:[Jsoi2015]salesman
    dp专题复习
    bzoj1864:[Zjoi2006]三色二叉树
    bzoj1190:[HNOI2007]梦幻岛宝珠
    bzoj2794:[Poi2012]Cloakroom
  • 原文地址:https://www.cnblogs.com/ganhang-acm/p/5164896.html
Copyright © 2011-2022 走看看