socket聊天室实现-群聊,私聊,好友列表,完整版

£神魔★判官ぃ 2022-12-01 14:16 277阅读 0赞

效果图

登录。好友上线,下线均提示。
登录
点击好友列表所有人,发送消息,既为群聊
群聊功能
点击好友列表,好友名字,既为选中此好友进行私聊
私聊功能

服务器端代码

ChatRoomServer

  1. package sram.server;
  2. import java.io.IOException;
  3. import java.net.ServerSocket;
  4. import java.net.Socket;
  5. import java.util.HashMap;
  6. import sram.thread.ChatRoomServerReaderThread;
  7. import sram.user.User;
  8. public class ChatRoomServer {
  9. private ServerSocket ss;
  10. public static HashMap<User, Socket> online = new HashMap<User, Socket>();
  11. public ChatRoomServer(){
  12. try {
  13. ss = new ServerSocket(6666);
  14. System.out.println("服务器已经开启,等待客户端...");
  15. while(true){
  16. Socket s = ss.accept();
  17. new Thread(new ChatRoomServerReaderThread(s)).start();
  18. }
  19. } catch (IOException e) {
  20. // TODO Auto-generated catch block
  21. e.printStackTrace();
  22. }
  23. }
  24. public static void main(String[] args) {
  25. new ChatRoomServer();
  26. }
  27. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

ChatRoomServerReaderThread

  1. package sram.thread;
  2. import java.io.BufferedReader;
  3. import java.io.IOException;
  4. import java.io.InputStreamReader;
  5. import java.io.PrintWriter;
  6. import java.net.Socket;
  7. import java.util.ArrayList;
  8. import java.util.List;
  9. import java.util.Set;
  10. import sram.server.ChatRoomServer;
  11. import sram.user.Message;
  12. import sram.user.User;
  13. import sram.util.SendMessageUtil;
  14. import net.sf.json.JSONArray;
  15. import net.sf.json.JSONObject;
  16. public class ChatRoomServerReaderThread implements Runnable {
  17. private Socket s;
  18. private BufferedReader br;
  19. private PrintWriter pw;
  20. private Message message;
  21. public ChatRoomServerReaderThread(Socket s) throws IOException {
  22. this.s = s;
  23. br = new BufferedReader(new InputStreamReader(s.getInputStream()));
  24. pw = new PrintWriter(s.getOutputStream(),true);
  25. }
  26. @Override
  27. public void run() {
  28. String str = null;
  29. try {
  30. while((str = br.readLine())!=null){
  31. message = new Message(); //返回的消息。
  32. System.out.println("发过来的消息是:"+str);
  33. Message msg =
  34. (Message) JSONObject.toBean
  35. (JSONObject.fromObject(str), Message.class);
  36. switch (msg.getType()) {
  37. case 1: //处理登录消息。
  38. User loginUser = msg.getFromUser();
  39. if(ChatRoomServer.online.containsKey(loginUser)){
  40. //用户名已经存在,不能登录
  41. message.setType(11);
  42. pw.println(JSONObject.fromObject(message).toString());
  43. }else{
  44. //用户名未存在,可以登录,返回可以登录的消息
  45. //获取所有用户
  46. List<User> users = new ArrayList<User>(ChatRoomServer.online.keySet());
  47. //List转化为JSON字符串
  48. message.setMessage(JSONArray.fromObject(users).toString());
  49. message.setType(10);
  50. ChatRoomServer.online.put(loginUser, s);
  51. pw.println(JSONObject.fromObject(message).toString());
  52. //用户登录成功后,系统发送系统消息给每个用户,告诉所有用户 XXX上线了。
  53. message.setType(4);
  54. message.setFromUser(loginUser);
  55. //调用群发方法,群发消息给所有用户。
  56. SendMessageUtil.sendMessage(ChatRoomServer.online, message);
  57. }
  58. break;
  59. case 3:
  60. User out = msg.getFromUser();
  61. ChatRoomServer.online.remove(out);
  62. message.setType(5);
  63. message.setFromUser(out);
  64. SendMessageUtil.sendMessage(ChatRoomServer.online, message);
  65. break;
  66. case 20: //处理私聊消息
  67. User toUser = msg.getToUser();
  68. Socket s = ChatRoomServer.online.get(toUser);
  69. PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
  70. msg.setType(22);
  71. pw.println(JSONObject.fromObject(msg).toString());
  72. break;
  73. case 21: //处理群聊消息
  74. msg.setType(23);
  75. SendMessageUtil.sendMessage(ChatRoomServer.online,msg);
  76. break;
  77. }
  78. if(msg.getType()==3){
  79. break;
  80. }
  81. }
  82. } catch (IOException e) {
  83. // TODO Auto-generated catch block
  84. e.printStackTrace();
  85. }
  86. }
  87. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95

Message

  1. package sram.user;
  2. //用来描述发送消息的类。 1登陆 2聊天 3退出 4系统消息等
  3. public class Message {
  4. private String message; //发送消息内容
  5. private int type; //发送消息类型
  6. private User fromUser; //来源自谁的消息
  7. private User toUser; //发送给谁
  8. public String getMessage() {
  9. return message;
  10. }
  11. public void setMessage(String message) {
  12. this.message = message;
  13. }
  14. public int getType() {
  15. return type;
  16. }
  17. public void setType(int type) {
  18. this.type = type;
  19. }
  20. public User getFromUser() {
  21. return fromUser;
  22. }
  23. public void setFromUser(User fromUser) {
  24. this.fromUser = fromUser;
  25. }
  26. public User getToUser() {
  27. return toUser;
  28. }
  29. public void setToUser(User toUser) {
  30. this.toUser = toUser;
  31. }
  32. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

User

  1. package sram.user;
  2. //用户实体类。登陆成功后,可以被保存在服务器端。
  3. public class User {
  4. private String username; //用户名,唯一的标识
  5. private String nickname;//用户自定义的网络名称
  6. public String getUsername() {
  7. return username;
  8. }
  9. public void setUsername(String username) {
  10. this.username = username;
  11. }
  12. public String getNickname() {
  13. return nickname;
  14. }
  15. public void setNickname(String nickname) {
  16. this.nickname = nickname;
  17. }
  18. public User(String username, String nickname) {
  19. this.username = username;
  20. this.nickname = nickname;
  21. }
  22. public User() {
  23. }
  24. @Override
  25. public int hashCode() {
  26. // TODO Auto-generated method stub
  27. return 0;
  28. }
  29. @Override
  30. public boolean equals(Object obj) {
  31. User user = (User)obj;
  32. return this.username.equals(user.username);
  33. }
  34. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

SendMessageUtil

  1. package sram.util;
  2. import java.io.IOException;
  3. import java.io.PrintWriter;
  4. import java.net.Socket;
  5. import java.util.Map;
  6. import java.util.Set;
  7. import net.sf.json.JSONObject;
  8. import sram.user.Message;
  9. import sram.user.User;
  10. public class SendMessageUtil {
  11. //群发的方法
  12. public static void sendMessage(Map<User, Socket> online,Message message) throws IOException{
  13. Set<User> users = online.keySet();
  14. for(User user :users){
  15. Socket s = online.get(user);
  16. PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
  17. pw.println(JSONObject.fromObject(message).toString());
  18. }
  19. }
  20. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

客户端代码

ClientFrame

  1. package sram.frame;
  2. import java.awt.BorderLayout;
  3. import java.awt.ScrollPane;
  4. import java.awt.event.ActionEvent;
  5. import java.awt.event.ActionListener;
  6. import java.awt.event.MouseAdapter;
  7. import java.awt.event.MouseEvent;
  8. import java.awt.event.WindowAdapter;
  9. import java.awt.event.WindowEvent;
  10. import java.io.IOException;
  11. import java.io.PrintWriter;
  12. import java.net.Socket;
  13. import java.text.SimpleDateFormat;
  14. import java.util.Date;
  15. import java.util.List;
  16. import javax.swing.JButton;
  17. import javax.swing.JFrame;
  18. import javax.swing.JLabel;
  19. import javax.swing.JOptionPane;
  20. import javax.swing.JPanel;
  21. import javax.swing.JScrollBar;
  22. import javax.swing.JScrollPane;
  23. import javax.swing.JTextArea;
  24. import javax.swing.JTextField;
  25. import javax.swing.JTree;
  26. import javax.swing.border.Border;
  27. import javax.swing.border.TitledBorder;
  28. import javax.swing.tree.DefaultMutableTreeNode;
  29. import javax.swing.tree.DefaultTreeModel;
  30. import net.sf.json.JSONObject;
  31. import sram.user.Message;
  32. import sram.user.User;
  33. public class ClientFrame {
  34. private JFrame frame; //主窗口
  35. private JTextArea area; //显示消息的文本域
  36. private JTextField text; //输入消息的文本框
  37. private JButton btnSend; //发送消息的按钮
  38. private JPanel p1,p2,p3; //布局使用的面板
  39. private TitledBorder b1,b2,b3;
  40. //好友列表使用JTree显示
  41. private JTree tree;
  42. private DefaultMutableTreeNode root;// 根节点
  43. private DefaultTreeModel model; //树模型
  44. private User user;
  45. private Socket socket;
  46. private PrintWriter pw;
  47. private User toUser = new User("All","所有人");
  48. private List<User> friends;
  49. public DefaultMutableTreeNode getRoot() {
  50. return root;
  51. }
  52. public void setRoot(DefaultMutableTreeNode root) {
  53. this.root = root;
  54. }
  55. public DefaultTreeModel getModel() {
  56. return model;
  57. }
  58. public void setModel(DefaultTreeModel model) {
  59. this.model = model;
  60. }
  61. public User getUser() {
  62. return user;
  63. }
  64. public void setUser(User user) {
  65. this.user = user;
  66. }
  67. public JTextArea getArea() {
  68. return area;
  69. }
  70. public void setArea(JTextArea area) {
  71. this.area = area;
  72. }
  73. public ClientFrame(User user,Socket socket,List<User> friends){
  74. this.user = user;//******************************************************
  75. this.socket = socket;//**************************************************
  76. this.friends = friends;//************************************************
  77. //调用init()方法初始化界面
  78. init();
  79. listener();
  80. }
  81. //初始化方法显示界面
  82. public void init(){
  83. //初始化对象**********************************************
  84. try {
  85. pw = new PrintWriter(socket.getOutputStream(),true);
  86. } catch (IOException e) {
  87. e.printStackTrace();
  88. }
  89. frame = new JFrame("当前用户:["+user.getNickname()+"("+user.getUsername()+")"+"]");
  90. area = new JTextArea();
  91. area.setEditable(false);
  92. area.setLineWrap(true);
  93. text = new JTextField(20);
  94. root = new DefaultMutableTreeNode("我的好友");
  95. model = new DefaultTreeModel(root);
  96. model.insertNodeInto(new DefaultMutableTreeNode(new User("All", "所有人")), root,root.getChildCount());
  97. //************************************************************************************
  98. if(friends!=null && friends.size()>0){
  99. for(User userf : friends){
  100. model.insertNodeInto(new DefaultMutableTreeNode(userf), root,root.getChildCount());
  101. }
  102. }
  103. //************************************************************************************
  104. tree = new JTree(model);
  105. //启用折叠显示
  106. tree.setShowsRootHandles(true);
  107. btnSend = new JButton("发送");
  108. b1 = new TitledBorder("好友列表");
  109. b2 = new TitledBorder("消息显示");
  110. b3 = new TitledBorder("发送消息");
  111. p1 = new JPanel(); //右边的面板,用来显示好友列表
  112. p2 = new JPanel(); //中间的面板,用来显示JTextArea
  113. p3 = new JPanel(); //下边的面板,用来显示文本输入框和发送按钮
  114. p1.setLayout(new BorderLayout());
  115. p2.setLayout(new BorderLayout());
  116. p1.setBorder(b1);
  117. p2.setBorder(b2);
  118. p3.setBorder(b3);
  119. p1.add(new JScrollPane(tree));
  120. p2.add(new JScrollPane(area,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER),BorderLayout.CENTER);
  121. p3.add(text);
  122. p3.add(btnSend);
  123. p2.add(p3,BorderLayout.SOUTH);
  124. frame.add(p1,BorderLayout.WEST);
  125. frame.add(p2,BorderLayout.CENTER);
  126. frame.setResizable(false);
  127. frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
  128. frame.setSize(500, 450);
  129. frame.setVisible(true);
  130. }
  131. public void listener(){
  132. frame.addWindowListener(new WindowAdapter() {
  133. @Override
  134. public void windowClosing(WindowEvent e) {
  135. int i = JOptionPane.showConfirmDialog(null, "您确定要退出聊天室?");
  136. if(i == JOptionPane.OK_OPTION){
  137. Message message = new Message();
  138. message.setType(3); //退出消息
  139. message.setFromUser(user);
  140. pw.println(JSONObject.fromObject(message).toString());
  141. try {
  142. Thread.sleep(100);
  143. System.exit(0);
  144. } catch (InterruptedException e1) {
  145. // TODO Auto-generated catch block
  146. e1.printStackTrace();
  147. }
  148. }
  149. }
  150. });
  151. tree.addMouseListener(new MouseAdapter() {
  152. @Override
  153. public void mouseClicked(MouseEvent e) {
  154. if(tree.getSelectionPath()!=null && tree.getSelectionPath().getParentPath()!=null){
  155. //获取点击节点的行数//*********************************************
  156. int i = tree.getLeadSelectionRow();
  157. DefaultMutableTreeNode node
  158. = (DefaultMutableTreeNode) root.getChildAt(i-1);
  159. toUser = (User) node.getUserObject();
  160. frame.setTitle("当前用户:["+user.getNickname()
  161. +"("+user.getUsername()+")"+"] 和 ["+toUser.getNickname()
  162. +"("+toUser.getUsername()+")"+"]的聊天");
  163. }
  164. }
  165. });
  166. btnSend.addActionListener(new ActionListener() {
  167. @Override
  168. public void actionPerformed(ActionEvent e) {
  169. //私聊 群聊
  170. Date date = new Date();
  171. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  172. String msg = text.getText();
  173. if(msg!=null && !msg.equals("")){
  174. Message message = new Message();
  175. message.setMessage(msg);
  176. message.setFromUser(user);
  177. text.setText("");
  178. if(toUser!=null){
  179. if(toUser.getUsername().equals("All")){
  180. message.setType(21);
  181. area.append("【群聊】"+user.getNickname()
  182. +"("+user.getUsername()+") "+sdf.format(date)+" 说:");
  183. area.append(msg+"\r\n");
  184. }else{
  185. message.setType(20);
  186. area.append("【私聊】"+user.getNickname()
  187. +"("+user.getUsername()+") "+sdf.format(date)+" 说:");
  188. area.append(msg+"\r\n");
  189. }
  190. }
  191. message.setToUser(toUser);
  192. pw.println(JSONObject.fromObject(message).toString());
  193. }
  194. }
  195. });
  196. }
  197. public static void main(String[] args) {
  198. //new ClientFrame(new User(),new Socket());
  199. }
  200. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212

LoginFrame

  1. package sram.frame;
  2. import java.awt.Dimension;
  3. import java.awt.GridLayout;
  4. import java.awt.Toolkit;
  5. import java.awt.event.ActionEvent;
  6. import java.awt.event.ActionListener;
  7. import java.io.BufferedReader;
  8. import java.io.IOException;
  9. import java.io.InputStreamReader;
  10. import java.io.PrintWriter;
  11. import java.net.Socket;
  12. import java.net.UnknownHostException;
  13. import java.util.List;
  14. import javax.swing.JButton;
  15. import javax.swing.JFrame;
  16. import javax.swing.JLabel;
  17. import javax.swing.JOptionPane;
  18. import javax.swing.JPanel;
  19. import javax.swing.JTextField;
  20. import net.sf.json.JSONArray;
  21. import net.sf.json.JSONObject;
  22. import sram.thread.ChatRoomClientReaderThread;
  23. import sram.user.Message;
  24. import sram.user.User;
  25. public class LoginFrame {
  26. private JFrame frame;
  27. private JLabel usernameLabel;
  28. private JLabel nicknameLabel;
  29. private JTextField usernameText;
  30. private JTextField nicknameText;
  31. private JButton btnRest;
  32. private JButton btnLogin;
  33. private JPanel p1,p2,p3;
  34. public LoginFrame(){
  35. init();
  36. listener();
  37. }
  38. public void init(){
  39. frame = new JFrame();
  40. usernameLabel = new JLabel("用户名");
  41. nicknameLabel = new JLabel("昵 称");
  42. usernameText = new JTextField(10);
  43. nicknameText = new JTextField(10);
  44. btnRest = new JButton("重置");
  45. btnLogin = new JButton("登录");
  46. p1 = new JPanel();
  47. p2 = new JPanel();
  48. p3 = new JPanel();
  49. frame.setLayout(new GridLayout(3, 1));
  50. p1.add(usernameLabel);
  51. p1.add(usernameText);
  52. p2.add(nicknameLabel);
  53. p2.add(nicknameText);
  54. p3.add(btnRest);
  55. p3.add(btnLogin);
  56. frame.add(p1);
  57. frame.add(p2);
  58. frame.add(p3);
  59. frame.setResizable(false);
  60. frame.pack();
  61. Toolkit t = Toolkit.getDefaultToolkit(); //获取工具包
  62. Dimension d = t.getScreenSize(); //获取屏幕尺寸
  63. frame.setLocation(d.width/2-175,d.height/2-40);
  64. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  65. frame.setVisible(true);
  66. }
  67. public void listener(){
  68. btnLogin.addActionListener(new ActionListener() {
  69. @Override
  70. public void actionPerformed(ActionEvent e) {
  71. String username = usernameText.getText();
  72. String nickname = nicknameText.getText();
  73. User user = new User(username,nickname);
  74. Message msg = new Message();
  75. msg.setType(1);
  76. msg.setFromUser(user);
  77. try {
  78. Socket s = new Socket("127.0.0.1",6666);
  79. PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
  80. pw.println(JSONObject.fromObject(msg).toString());
  81. BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
  82. String message = br.readLine();
  83. System.out.println("客户端接受的消息是:"+message);
  84. Message msgReturn =
  85. (Message) JSONObject.toBean
  86. (JSONObject.fromObject(message), Message.class);
  87. switch (msgReturn.getType()) {
  88. case 10:
  89. System.out.println("开启聊天窗口");
  90. String usersStr = msgReturn.getMessage();
  91. List<User> list = JSONArray.toList(JSONArray.fromObject(usersStr),User.class);
  92. ClientFrame f = new ClientFrame(user,s,list);
  93. new Thread(new ChatRoomClientReaderThread(s, f)).start();
  94. frame.setVisible(false);
  95. break;
  96. case 11:
  97. s.close();
  98. JOptionPane.showMessageDialog(null, "用户名已经存在,请重新输入后登录");
  99. break;
  100. default:
  101. break;
  102. }
  103. } catch (UnknownHostException e1) {
  104. // TODO Auto-generated catch block
  105. e1.printStackTrace();
  106. } catch (IOException e1) {
  107. // TODO Auto-generated catch block
  108. e1.printStackTrace();
  109. }
  110. }
  111. });
  112. }
  113. public static void main(String[] args) {
  114. new LoginFrame();
  115. }
  116. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126

ChatRoomClientReaderThread

  1. package sram.thread;
  2. import java.io.BufferedReader;
  3. import java.io.IOException;
  4. import java.io.InputStreamReader;
  5. import java.io.PrintWriter;
  6. import java.net.Socket;
  7. import java.text.SimpleDateFormat;
  8. import java.util.Date;
  9. import net.sf.json.JSONObject;
  10. import sram.frame.ClientFrame;
  11. import sram.user.Message;
  12. import sram.user.User;
  13. import sram.util.FriendsTreeFlushUtil;
  14. public class ChatRoomClientReaderThread implements Runnable {
  15. private Socket socket;
  16. private BufferedReader br ;
  17. private PrintWriter pw;
  18. private ClientFrame frame;
  19. public ChatRoomClientReaderThread(Socket socket,ClientFrame frame) throws IOException {
  20. this.socket = socket;
  21. this.frame = frame;
  22. br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
  23. pw = new PrintWriter(socket.getOutputStream(),true);
  24. }
  25. @Override
  26. public void run() {
  27. String str = null;
  28. try {
  29. while((str = br.readLine())!=null){
  30. Date date = new Date();
  31. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  32. System.out.println("客户端接收的消息是:"+str);
  33. Message msg =
  34. (Message) JSONObject.toBean
  35. (JSONObject.fromObject(str), Message.class);
  36. switch (msg.getType()) {
  37. case 4: //系统登录消息。
  38. User userLogin = msg.getFromUser();
  39. if(userLogin.equals(frame.getUser())){
  40. frame.getArea().append("[系统消息]:您成功上线了!\r\n");
  41. }else{
  42. frame.getArea().append("[系统消息]:您的好友"+userLogin.getNickname()+"("+userLogin.getUsername()+")上线了!\r\n");
  43. //好友列表增加用户
  44. FriendsTreeFlushUtil.insert(frame, userLogin);
  45. }
  46. break;
  47. case 5: //系统退出消息
  48. User out = msg.getFromUser();
  49. frame.getArea().append("[系统消息]:您的好友"+out.getNickname()+"("+out.getUsername()+")下线了!\r\n");
  50. //在好友列表中移除退出的用户
  51. FriendsTreeFlushUtil.remove(frame, out);
  52. break;
  53. case 22: //客户端接收的私聊消息
  54. User fromUser = msg.getFromUser();
  55. String msgStr = msg.getMessage();
  56. frame.getArea().append("【私聊】"+fromUser.getNickname()
  57. +"("+fromUser.getUsername()+") "+sdf.format(date)+" 说:");
  58. frame.getArea().append(msgStr+"\r\n");
  59. break;
  60. case 23: //客户端接收的群聊消息
  61. User fromU = msg.getFromUser();
  62. String msgS = msg.getMessage();
  63. if(!frame.getUser().equals(fromU)){
  64. frame.getArea().append("【群聊】"+fromU.getNickname()
  65. +"("+fromU.getUsername()+") "+sdf.format(date)+" 说:");
  66. frame.getArea().append(msgS+"\r\n");
  67. }
  68. break;
  69. }
  70. }
  71. } catch (IOException e) {
  72. e.printStackTrace();
  73. }
  74. }
  75. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85

Message

  1. package sram.user;
  2. //用来描述发送消息的类。 1登陆(10 成功 11 不成功) 2 (服务器(20 私聊 21 群聊)客户端( 22 私聊,23群聊 )聊天 3退出 4系统登录消息 5 系统退出消息等
  3. public class Message {
  4. private String message; //发送消息内容
  5. private int type; //发送消息类型
  6. private User fromUser; //来源自谁的消息
  7. private User toUser; //发送给谁
  8. public String getMessage() {
  9. return message;
  10. }
  11. public void setMessage(String message) {
  12. this.message = message;
  13. }
  14. public int getType() {
  15. return type;
  16. }
  17. public void setType(int type) {
  18. this.type = type;
  19. }
  20. public User getFromUser() {
  21. return fromUser;
  22. }
  23. public void setFromUser(User fromUser) {
  24. this.fromUser = fromUser;
  25. }
  26. public User getToUser() {
  27. return toUser;
  28. }
  29. public void setToUser(User toUser) {
  30. this.toUser = toUser;
  31. }
  32. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

User

  1. package sram.user;
  2. //用户实体类。登陆成功后,可以被保存在服务器端。
  3. public class User {
  4. private String username; //用户名,唯一的标识
  5. private String nickname;//用户自定义的网络名称
  6. public String getUsername() {
  7. return username;
  8. }
  9. public void setUsername(String username) {
  10. this.username = username;
  11. }
  12. public String getNickname() {
  13. return nickname;
  14. }
  15. public void setNickname(String nickname) {
  16. this.nickname = nickname;
  17. }
  18. public User(String username, String nickname) {
  19. this.username = username;
  20. this.nickname = nickname;
  21. }
  22. public User() {
  23. }
  24. @Override
  25. public boolean equals(Object obj) {
  26. User user = (User)obj;
  27. return this.username.equals(user.username);
  28. }
  29. @Override
  30. public String toString() {
  31. return nickname+"("+username+")";
  32. }
  33. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

FriendsTreeFlushUtil

  1. package sram.util;
  2. import java.util.Enumeration;
  3. import javax.swing.tree.DefaultMutableTreeNode;
  4. import javax.swing.tree.DefaultTreeModel;
  5. import sram.frame.ClientFrame;
  6. import sram.user.User;
  7. public class FriendsTreeFlushUtil {
  8. public static void insert(ClientFrame frame,User u){
  9. DefaultMutableTreeNode root = frame.getRoot();
  10. DefaultTreeModel model = frame.getModel();
  11. model.insertNodeInto(new DefaultMutableTreeNode(u), root, root.getChildCount());
  12. }
  13. public static void remove(ClientFrame frame,User u){
  14. DefaultMutableTreeNode root = frame.getRoot();
  15. DefaultTreeModel model = frame.getModel();
  16. //获取所有的子节点
  17. Enumeration<DefaultMutableTreeNode> children = root.children();
  18. while(children.hasMoreElements()){
  19. DefaultMutableTreeNode node = children.nextElement();
  20. User user = (User) node.getUserObject();
  21. if(user.equals(u)){
  22. model.removeNodeFromParent(node);
  23. }
  24. }
  25. }
  26. }

发表评论

表情:
评论列表 (有 0 条评论,277人围观)

还没有评论,来说两句吧...

相关阅读