java學習之即時通訊項目實戰

 項目總結:此次項目主要是根據視頻來的,結果跟到一半感受跟不上,慢慢本身有了本身的想法,決定本身先不看學習視頻,本身先試着寫。java

  總結寫前面,算是寫的第一個項目吧。項目中遇到幾點問題,首先Scoket對象建立後,服務器端和客戶端不能同時建立輸入流,否者會引發堵塞。git

  而後,讀入流應該從新建立個線程作等待寫入服務,由於讀入流會引發當前線程進入阻塞狀態。github

     還有一個用戶線程對應一個服務線程,不是多個用戶線程對應一個服務線程。數據庫

     對對象的操做應該由那個對象自己提供操做方法,好比操做UI界面的變化應該由界面自己提拱。服務器

  最後最重要的是寫代碼以前應該先畫個流程圖,寫代碼時參數亂傳的,哪裏須要就調參數過來。致使思路不清.app

首先是需求分析:ide

  本次項目是模擬及時通訊中最基本的功能,相似QQ的應用.模塊化

  項目分爲:學習

   (1)服務器端:this

    服務器端主要負責用戶管理,消息轉發功能

   (2) 客戶端:

    客戶端主要負責用戶間的消息發送

詳細設計

服務器端

  一、登陸服務器後,進行客戶端的監聽,若有客戶端鏈接,啓動用戶服務線程,與客戶端進行交互。

  二、如客戶端向全部人發送消息,服務器將向全部在線用戶廣播該消息。

      三、如客戶端向指定人發送消息,服務器將查找接收人用戶線程後轉發消息。

      四、用戶登陸後,向全部人更新用戶列表。

客戶端:

一、用戶登陸功能。

二、登陸後用戶能夠看到在線用戶列表

3 、向指定人發送消息

四、向全部人發送消息

代碼的實現

首先,先構建界面圖形出來

 

上面左邊是用戶界面(服務器界面和用戶界面同樣),右邊是登陸界面

因爲全用手寫代碼比較麻煩,我用了可視化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() + "\n").append(text).append("\n");
 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("\u804A\u804A-\u5BA2\u6237\u7AEF");
 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("--\u5728\u7EBF\u7528\u6237\u5217\u8868--");
 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("\u8BF7\u8F93\u5165\uFF1A");
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("\u53D1\u9001");
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("\u767B\u5F55");
 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("\u7528\u6237\u5E10\u53F7\uFF1A");
 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("\u7528\u6237\u5BC6\u7801\uFF1A");
 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("\u767B\u5F55");
 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("\u9000\u51FA");
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("\n").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("\u804A\u804A-\u670D\u52A1\u7AEF");
 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("\u670D\u52A1\u5668\u7AEF");
 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("--\u5728\u7EBF\u7528\u6237\u5217\u8868--");
 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("\u8BF7\u8F93\u5165\uFF1A");
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("\u53D1\u9001");
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

相關文章
相關標籤/搜索