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

  • 相关阅读:
    iSCSI又称为IPSAN
    文档类型定义DTD
    HDU 2971 Tower
    HDU 1588 Gauss Fibonacci
    URAL 1005 Stone Pile
    URAL 1003 Parity
    URAL 1002 Phone Numbers
    URAL 1007 Code Words
    HDU 3306 Another kind of Fibonacci
    FZU 1683 纪念SlingShot
  • 原文地址:https://www.cnblogs.com/ganhang-acm/p/5164896.html
Copyright © 2011-2022 走看看