服务器端:
ChatServer.java
包含名为ChatServer的public类,其主要功能为定义服务器端的界面,添加时间监听与时间处理。调用ServerListen类来实现服务端用户上线与下线的监听,调用ServerListen来实现服务器端的消息收发。
1 package com.silianbo.server; 2 3 import com.silianbo.CaptureScreen; 4 import java.awt.BorderLayout; 5 import java.awt.Container; 6 import java.awt.Dimension; 7 import java.awt.GridBagConstraints; 8 import java.awt.GridBagLayout; 9 import java.awt.Insets; 10 import java.awt.Toolkit; 11 import java.awt.event.ActionEvent; 12 import java.awt.event.ActionListener; 13 import java.awt.event.WindowAdapter; 14 import java.awt.event.WindowEvent; 15 import java.net.ServerSocket; 16 import javax.swing.JButton; 17 import javax.swing.JComboBox; 18 import javax.swing.JFrame; 19 import javax.swing.JLabel; 20 import javax.swing.JMenu; 21 import javax.swing.JMenuBar; 22 import javax.swing.JMenuItem; 23 import javax.swing.JOptionPane; 24 import javax.swing.JPanel; 25 import javax.swing.JScrollPane; 26 import javax.swing.JTextArea; 27 import javax.swing.JTextField; 28 import javax.swing.JToolBar; 29 import javax.swing.UIManager; 30 import javax.swing.UnsupportedLookAndFeelException; 31 32 public final class ChatServer extends JFrame implements ActionListener { 33 34 private static final long serialVersionUID = 1L; 35 36 public static int port = 8888; 37 38 ServerSocket serverSocket; 39 40 JComboBox combobox; 41 42 JTextArea messageShow; 43 44 JScrollPane messageScrollPane; 45 46 JTextField showStatus; 47 48 JLabel sendToLabel, messageLabel; 49 50 JTextField sysMessage; 51 52 JButton sysMessageButton; 53 54 UserLinkList userLinkList; 55 56 JMenuBar jMenuBar = new JMenuBar(); 57 58 JMenu serviceMenu = new JMenu("服务"); 59 60 JMenuItem portItem = new JMenuItem("端口设置"); 61 62 JMenuItem startItem = new JMenuItem("启动服务"); 63 64 JMenuItem stopItem = new JMenuItem("停止服务"); 65 66 JMenuItem exitItem = new JMenuItem("退出"); 67 68 JMenu helpMenu = new JMenu("帮助"); 69 70 JMenuItem helpItem = new JMenuItem("帮助"); 71 72 JToolBar toolBar = new JToolBar(); 73 74 JButton portSet; 75 76 JButton startServer; 77 78 JButton stopServer; 79 80 JButton exitButton; 81 82 JButton uploadButton; 83 84 Dimension faceSize = new Dimension(550, 550); 85 86 ServerListen listenThread; 87 88 JPanel downPanel; 89 90 GridBagLayout girdBag; 91 92 GridBagConstraints girdBagCon; 93 94 public ChatServer() { 95 init(); 96 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 97 this.pack(); 98 this.setSize(faceSize); 99 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); 100 this.setLocation((int) (screenSize.width - faceSize.getWidth()) / 2, (int) (screenSize.height - faceSize.getHeight()) / 2); 101 this.setResizable(false); 102 this.setTitle("聊天室服务器端"); 103 setVisible(true); 104 } 105 106 public void init() { 107 Container contentPane = getContentPane(); 108 contentPane.setLayout(new BorderLayout()); 109 serviceMenu.add(startItem); 110 serviceMenu.add(stopItem); 111 serviceMenu.add(exitItem); 112 jMenuBar.add(serviceMenu); 113 helpMenu.add(helpItem); 114 JMenu add = jMenuBar.add(helpMenu); 115 setJMenuBar(jMenuBar); 116 portSet = new JButton("端口设置"); 117 startServer = new JButton("启动服务"); 118 stopServer = new JButton("停止服务"); 119 exitButton = new JButton("退出"); 120 toolBar.add(portSet); 121 toolBar.addSeparator(); 122 toolBar.add(startServer); 123 toolBar.add(stopServer); 124 toolBar.addSeparator(); 125 toolBar.add(exitButton); 126 contentPane.add(toolBar, BorderLayout.NORTH); 127 stopServer.setEnabled(false); 128 stopItem.setEnabled(false); 129 portItem.addActionListener(this); 130 startItem.addActionListener(this); 131 stopItem.addActionListener(this); 132 exitItem.addActionListener(this); 133 helpItem.addActionListener(this); 134 portSet.addActionListener(this); 135 startServer.addActionListener(this); 136 stopServer.addActionListener(this); 137 exitButton.addActionListener(this); 138 combobox = new JComboBox(); 139 combobox.insertItemAt("所有人", 0); 140 combobox.setSelectedIndex(0); 141 messageShow = new JTextArea(); 142 messageShow.setEditable(false); 143 messageScrollPane = new JScrollPane(messageShow, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); 144 messageScrollPane.setPreferredSize(new Dimension(400, 400)); 145 messageScrollPane.revalidate(); 146 showStatus = new JTextField(25); 147 showStatus.setEditable(false); 148 sysMessage = new JTextField(25); 149 sysMessage.setEnabled(false); 150 sysMessageButton = new JButton(); 151 sysMessageButton.setText("发送"); 152 sysMessage.addActionListener(this); 153 sysMessageButton.addActionListener(this); 154 sendToLabel = new JLabel("发送至:"); 155 messageLabel = new JLabel("发送消息:"); 156 downPanel = new JPanel(); 157 girdBag = new GridBagLayout(); 158 downPanel.setLayout(girdBag); 159 girdBagCon = new GridBagConstraints(); 160 girdBagCon.gridx = 0; 161 girdBagCon.gridy = 0; 162 girdBagCon.gridwidth = 3; 163 girdBagCon.gridheight = 2; 164 girdBagCon.ipadx = 5; 165 girdBagCon.ipady = 5; 166 JLabel none = new JLabel(" "); 167 girdBag.setConstraints(none, girdBagCon); 168 downPanel.add(none); 169 girdBagCon = new GridBagConstraints(); 170 girdBagCon.gridx = 0; 171 girdBagCon.gridy = 2; 172 girdBagCon.insets = new Insets(1, 0, 0, 0); 173 girdBagCon.ipadx = 5; 174 girdBagCon.ipady = 5; 175 girdBag.setConstraints(sendToLabel, girdBagCon); 176 downPanel.add(sendToLabel); 177 girdBagCon = new GridBagConstraints(); 178 girdBagCon.gridx = 1; 179 girdBagCon.gridy = 2; 180 girdBagCon.anchor = GridBagConstraints.LINE_START; 181 girdBag.setConstraints(combobox, girdBagCon); 182 downPanel.add(combobox); 183 girdBagCon = new GridBagConstraints(); 184 girdBagCon.gridx = 0; 185 girdBagCon.gridy = 3; 186 girdBag.setConstraints(messageLabel, girdBagCon); 187 downPanel.add(messageLabel); 188 girdBagCon = new GridBagConstraints(); 189 girdBagCon.gridx = 1; 190 girdBagCon.gridy = 3; 191 girdBag.setConstraints(sysMessage, girdBagCon); 192 downPanel.add(sysMessage); 193 girdBagCon = new GridBagConstraints(); 194 girdBagCon.gridx = 2; 195 girdBagCon.gridy = 3; 196 girdBag.setConstraints(sysMessageButton, girdBagCon); 197 downPanel.add(sysMessageButton); 198 girdBagCon = new GridBagConstraints(); 199 girdBagCon.gridx = 0; 200 girdBagCon.gridy = 4; 201 girdBagCon.gridwidth = 3; 202 girdBag.setConstraints(showStatus, girdBagCon); 203 downPanel.add(showStatus); 204 contentPane.add(messageScrollPane, BorderLayout.CENTER); 205 contentPane.add(downPanel, BorderLayout.SOUTH); 206 this.addWindowListener(new WindowAdapter() { 207 208 @Override 209 public void windowClosing(WindowEvent e) { 210 stopService(); 211 System.exit(0); 212 } 213 }); 214 } 215 216 @Override 217 public void actionPerformed(ActionEvent e) { 218 Object obj = e.getSource(); 219 if (obj == startServer || obj == startItem) { 220 startService(); 221 } else if (obj == stopServer || obj == stopItem) { 222 int j = JOptionPane.showConfirmDialog(this, "真的停止服务吗?", "停止服务", JOptionPane.YES_OPTION, JOptionPane.QUESTION_MESSAGE); 223 if (j == JOptionPane.YES_OPTION) { 224 stopService(); 225 } 226 } else if (obj == portSet || obj == portItem) { 227 PortConf portConf = new PortConf(this); 228 portConf.setVisible(true); 229 } else if (obj == exitButton || obj == exitItem) { 230 int j = JOptionPane.showConfirmDialog(this, "真的要退出吗?", "退出", JOptionPane.YES_OPTION, JOptionPane.QUESTION_MESSAGE); 231 if (j == JOptionPane.YES_OPTION) { 232 stopService(); 233 System.exit(0); 234 } 235 } else if (obj == helpItem) { 236 CaptureScreen.RandomName.Help helpDialog = new CaptureScreen.RandomName.Help(this); 237 helpDialog.setVisible(true); 238 } else if (obj == sysMessage || obj == sysMessageButton) { 239 sendSystemMessage(); 240 } 241 } 242 243 public void startService() { 244 try { 245 serverSocket = new ServerSocket(port, 10); 246 messageShow.append("服务端已经启动,在" + port + "端口侦听...\n"); 247 startServer.setEnabled(false); 248 startItem.setEnabled(false); 249 portSet.setEnabled(false); 250 portItem.setEnabled(false); 251 stopServer.setEnabled(true); 252 stopItem.setEnabled(true); 253 sysMessage.setEnabled(true); 254 } catch (Exception e) { 255 } 256 userLinkList = new UserLinkList(); 257 listenThread = new ServerListen(serverSocket, combobox, messageShow, showStatus, userLinkList); 258 listenThread.start(); 259 } 260 261 public void stopService() { 262 try { 263 sendStopToAll(); 264 listenThread.isStop = true; 265 serverSocket.close(); 266 int count = userLinkList.getCount(); 267 int i = 0; 268 while (i < count) { 269 Node node = userLinkList.findUser(i); 270 node.input.close(); 271 node.output.close(); 272 node.socket.close(); 273 i++; 274 } 275 stopServer.setEnabled(false); 276 stopItem.setEnabled(false); 277 startServer.setEnabled(true); 278 startItem.setEnabled(true); 279 portSet.setEnabled(true); 280 portItem.setEnabled(true); 281 sysMessage.setEnabled(false); 282 messageShow.append("服务端已经关闭\n"); 283 combobox.removeAllItems(); 284 combobox.addItem("所有人"); 285 } catch (Exception e) { 286 } 287 } 288 289 public void sendStopToAll() { 290 int count = userLinkList.getCount(); 291 int i = 0; 292 while (i < count) { 293 Node node = userLinkList.findUser(i); 294 if (node == null) { 295 i++; 296 continue; 297 } 298 try { 299 node.output.writeObject("服务关闭"); 300 node.output.flush(); 301 } catch (Exception e) { 302 } 303 i++; 304 } 305 } 306 307 public void sendMsgToAll(String msg) { 308 int count = userLinkList.getCount(); 309 int i = 0; 310 while (i < count) { 311 Node node = userLinkList.findUser(i); 312 if (node == null) { 313 i++; 314 continue; 315 } 316 try { 317 node.output.writeObject("系统信息"); 318 node.output.flush(); 319 node.output.writeObject(msg); 320 node.output.flush(); 321 } catch (Exception e) { 322 } 323 i++; 324 } 325 sysMessage.setText(""); 326 } 327 328 public void sendSystemMessage() { 329 String toSomebody = combobox.getSelectedItem().toString(); 330 String message = sysMessage.getText() + "\n"; 331 messageShow.append(message); 332 if (toSomebody.equalsIgnoreCase("所有人")) { 333 sendMsgToAll(message); 334 } else { 335 Node node; 336 node = userLinkList.findUser(toSomebody); 337 try { 338 node.output.writeObject("系统信息"); 339 node.output.flush(); 340 node.output.writeObject(message); 341 node.output.flush(); 342 } catch (Exception e) { 343 } 344 sysMessage.setText(""); 345 } 346 } 347 348 public static void main(String[] args) { 349 try { 350 UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 351 } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) { 352 } 353 ChatServer chatServer = new ChatServer(); 354 } 355 }
ServerListen.java
该类实现服务器用户上线与下线的监听。该类对用户上线下线的监听是通过调用用户链表类(UserLinkList)来实现的。当用户上线与下线情况发生变化时,该类会对主类的界面进行相应的修改。
1 package com.silianbo.server; 2 3 import javax.swing.*; 4 import java.io.*; 5 import java.net.*; 6 7 public class ServerListen extends Thread { 8 9 ServerSocket server; 10 11 JComboBox combobox; 12 13 JTextArea textarea; 14 15 JTextField textfield; 16 17 UserLinkList userLinkList; 18 19 Node client; 20 21 ServerReceive recvThread; 22 23 public boolean isStop; 24 25 public ServerListen(ServerSocket server, JComboBox combobox, JTextArea textarea, JTextField textfield, UserLinkList userLinkList) { 26 this.server = server; 27 this.combobox = combobox; 28 this.textarea = textarea; 29 this.textfield = textfield; 30 this.userLinkList = userLinkList; 31 isStop = false; 32 } 33 34 @Override 35 public void run() { 36 while (!isStop && !server.isClosed()) { 37 try { 38 client = new Node(); 39 client.socket = server.accept(); 40 client.output = new ObjectOutputStream(client.socket.getOutputStream()); 41 client.output.flush(); 42 client.input = new ObjectInputStream(client.socket.getInputStream()); 43 client.username = (String) client.input.readObject(); 44 combobox.addItem(client.username); 45 userLinkList.addUser(client); 46 textarea.append("用户 " + client.username + " 上线" + "\n"); 47 textfield.setText("在线用户" + userLinkList.getCount() + "人\n"); 48 recvThread = new ServerReceive(textarea, textfield, combobox, client, userLinkList); 49 recvThread.start(); 50 } catch (IOException | ClassNotFoundException e) { 51 } 52 } 53 } 54 }
ServerReceive.java
该类是实现服务器消息收发的类,该类分别定义了向某用户及所有人发送消息的方法,发送的消息会显示在主界面类的街面上。
1 package com.silianbo.server; 2 3 import java.io.IOException; 4 import javax.swing.*; 5 6 public class ServerReceive extends Thread { 7 8 JTextArea textarea; 9 10 JTextField textfield; 11 12 JComboBox combobox; 13 14 Node client; 15 16 UserLinkList userLinkList; 17 18 public boolean isStop; 19 20 public ServerReceive(JTextArea textarea, JTextField textfield, JComboBox combobox, Node client, UserLinkList userLinkList) { 21 this.textarea = textarea; 22 this.textfield = textfield; 23 this.client = client; 24 this.userLinkList = userLinkList; 25 this.combobox = combobox; 26 isStop = false; 27 } 28 29 @Override 30 public void run() { 31 sendUserList(); 32 while (!isStop && !client.socket.isClosed()) { 33 try { 34 String type = (String) client.input.readObject(); 35 if (type.equalsIgnoreCase("聊天信息")) { 36 String toSomebody = (String) client.input.readObject(); 37 String status = (String) client.input.readObject(); 38 String action = (String) client.input.readObject(); 39 String message = (String) client.input.readObject(); 40 String msg = client.username + " " + action + "对 " + toSomebody + " 说 : " + message + "\n"; 41 if (status.equalsIgnoreCase("悄悄话")) { 42 msg = " [悄悄话] " + msg; 43 } 44 textarea.append(msg); 45 if (toSomebody.equalsIgnoreCase("所有人")) { 46 sendToAll(msg); 47 } else { 48 try { 49 client.output.writeObject("聊天信息"); 50 client.output.flush(); 51 client.output.writeObject(msg); 52 client.output.flush(); 53 } catch (Exception e) { 54 } 55 Node node = userLinkList.findUser(toSomebody); 56 if (node != null) { 57 node.output.writeObject("聊天信息"); 58 node.output.flush(); 59 node.output.writeObject(msg); 60 node.output.flush(); 61 } 62 } 63 } else if (type.equalsIgnoreCase("用户下线")) { 64 Node node = userLinkList.findUser(client.username); 65 userLinkList.delUser(node); 66 String msg = "用户 " + client.username + " 下线\n"; 67 int count = userLinkList.getCount(); 68 combobox.removeAllItems(); 69 combobox.addItem("所有人"); 70 int i = 0; 71 while (i < count) { 72 node = userLinkList.findUser(i); 73 if (node == null) { 74 i++; 75 continue; 76 } 77 combobox.addItem(node.username); 78 i++; 79 } 80 combobox.setSelectedIndex(0); 81 textarea.append(msg); 82 textfield.setText("在线用户" + userLinkList.getCount() + "人\n"); 83 sendToAll(msg); 84 sendUserList(); 85 break; 86 } 87 } catch (IOException | ClassNotFoundException e) { 88 } 89 } 90 } 91 92 public void sendToAll(String msg) { 93 int count = userLinkList.getCount(); 94 int i = 0; 95 while (count > 0) { 96 Node node = userLinkList.findUser(i); 97 if (node == null) { 98 i++; 99 continue; 100 } 101 try { 102 node.output.writeObject("聊天信息"); 103 node.output.flush(); 104 node.output.writeObject(msg); 105 node.output.flush(); 106 } catch (Exception e) { 107 } 108 i++; 109 } 110 } 111 112 public void sendUserList() { 113 String userlist = ""; 114 int count = userLinkList.getCount(); 115 int i = 0; 116 while (i < count) { 117 Node node = userLinkList.findUser(i); 118 if (node == null) { 119 i++; 120 continue; 121 } 122 userlist += node.username; 123 userlist += '\n'; 124 i++; 125 } 126 i = 0; 127 while (i < count) { 128 Node node = userLinkList.findUser(i); 129 if (node == null) { 130 i++; 131 continue; 132 } 133 try { 134 node.output.writeObject("用户列表"); 135 node.output.flush(); 136 node.output.writeObject(userlist); 137 node.output.flush(); 138 } catch (Exception e) { 139 } 140 i++; 141 } 142 } 143 }
PortConf.java
该类继承自Jdialog,是用户对服务器端监听端口进行修改配置的类
1 /* 2 * To change this license header, choose License Headers in Project Properties. 3 * To change this template file, choose Tools | Templates 4 * and open the template in the editor. 5 */ 6 package com.silianbo.server; 7 8 /** 9 * 10 * @author silianbo 11 * 生成端口设置对话框的类 12 */ 13 import java.awt.*; 14 import javax.swing.*; 15 import java.awt.event.*; 16 17 18 public class PortConf extends JDialog { 19 /** 20 * 21 */ 22 private static final long serialVersionUID = 1L; 23 JPanel panelPort = new JPanel(); 24 JButton save = new JButton(); 25 JButton cancel = new JButton(); 26 public static JLabel DLGINFO=new JLabel( 27 " 默认端口号为:8888"); 28 29 JPanel panelSave = new JPanel(); 30 JLabel message = new JLabel(); 31 32 public static JTextField portNumber ; 33 34 public PortConf(JFrame frame) { 35 super(frame, true); 36 try { 37 jbInit(); 38 } 39 catch (Exception e) { 40 } 41 //设置运行位置,使对话框居中 42 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); 43 this.setLocation( (int) (screenSize.width - 400) / 2 + 50, 44 (int) (screenSize.height - 600) / 2 + 150); 45 this.setResizable(false); 46 } 47 48 private void jbInit() throws Exception { 49 this.setSize(new Dimension(300, 120)); 50 this.setTitle("端口设置"); 51 message.setText("请输入侦听的端口号:"); 52 portNumber = new JTextField(10); 53 portNumber.setText(""+ChatServer.port); 54 save.setText("保存"); 55 cancel.setText("取消"); 56 57 panelPort.setLayout(new FlowLayout()); 58 panelPort.add(message); 59 panelPort.add(portNumber); 60 61 panelSave.add(new Label(" ")); 62 panelSave.add(save); 63 panelSave.add(cancel); 64 panelSave.add(new Label(" ")); 65 66 Container contentPane = getContentPane(); 67 contentPane.setLayout(new BorderLayout()); 68 contentPane.add(panelPort, BorderLayout.NORTH); 69 contentPane.add(DLGINFO, BorderLayout.CENTER); 70 contentPane.add(panelSave, BorderLayout.SOUTH); 71 72 //保存按钮的事件处理 73 save.addActionListener((ActionEvent a) -> { 74 int savePort; 75 try{ 76 77 savePort=Integer.parseInt(PortConf.portNumber.getText()); 78 79 if(savePort<1 || savePort>65535){ 80 PortConf.DLGINFO.setText(" 侦听端口必须是0-65535之间的整数!"); 81 PortConf.portNumber.setText(""); 82 return; 83 } 84 ChatServer.port = savePort; 85 dispose(); 86 } 87 catch(NumberFormatException e){ 88 PortConf.DLGINFO.setText(" 错误的端口号,端口号请填写整数!"); 89 PortConf.portNumber.setText(""); 90 } 91 }); 92 93 //关闭对话框时的操作 94 this.addWindowListener( 95 new WindowAdapter(){ 96 @Override 97 public void windowClosing(WindowEvent e){ 98 DLGINFO.setText(" 默认端口号为:8888"); 99 } 100 } 101 ); 102 103 //取消按钮的事件处理 104 cancel.addActionListener((ActionEvent e) -> { 105 DLGINFO.setText(" 默认端口号为:8888"); 106 dispose(); 107 }); 108 } 109 }
Help.java
服务端程序帮助类。
1 mport java.awt.*; 2 import javax.swing.*; 3 import java.awt.event.*; 4 5 /** 6 * 生成设置对话框的类 7 */ 8 public class Help extends JDialog { 9 10 /** 11 * 12 */ 13 private static final long serialVersionUID = 1L; 14 JPanel titlePanel = new JPanel(); 15 JPanel contentPanel = new JPanel(); 16 JPanel closePanel = new JPanel(); 17 18 JButton close = new JButton(); 19 JLabel title = new JLabel("聊天室服务端帮助"); 20 JTextArea help = new JTextArea(); 21 22 Color bg = new Color(255,255,255); 23 24 public Help(JFrame frame) { 25 super(frame, true); 26 try { 27 jbInit(); 28 } 29 catch (Exception e) { 30 e.printStackTrace(); 31 } 32 //设置运行位置,使对话框居中 33 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); 34 this.setLocation( (int) (screenSize.width - 400) / 2, 35 (int) (screenSize.height - 320) / 2); 36 this.setResizable(false); 37 } 38 39 private void jbInit() throws Exception { 40 this.setSize(new Dimension(400, 200)); 41 this.setTitle("帮助"); 42 43 titlePanel.setBackground(bg);; 44 contentPanel.setBackground(bg); 45 closePanel.setBackground(bg); 46 47 help.setText("1、设置服务端的侦听端口(默认端口为8888)。\n"+ 48 "2、点击 启动服务 按钮便可在指定的端口启动服务。\n"+ 49 "3、选择需要接受消息的用户,在消息栏中写入消息,之后便可发送消息。\n"+ 50 "4、信息状态栏中显示服务器当前的启动与停止状态、"+ 51 "用户发送的消息和\n 服务器端发送的系统消息。"); 52 help.setEditable(false); 53 54 titlePanel.add(new Label(" ")); 55 titlePanel.add(title); 56 titlePanel.add(new Label(" ")); 57 58 contentPanel.add(help); 59 60 closePanel.add(new Label(" ")); 61 closePanel.add(close); 62 closePanel.add(new Label(" ")); 63 64 Container contentPane = getContentPane(); 65 contentPane.setLayout(new BorderLayout()); 66 contentPane.add(titlePanel, BorderLayout.NORTH); 67 contentPane.add(contentPanel, BorderLayout.CENTER); 68 contentPane.add(closePanel, BorderLayout.SOUTH); 69 70 close.setText("关闭"); 71 //事件处理 72 close.addActionListener( 73 new ActionListener() { 74 public void actionPerformed(ActionEvent e) { 75 dispose(); 76 } 77 } 78 ); 79 } 80 }
UserLinkList.java
用户链表节点的具体实现类。该类通过构造函数构造用户链表,定义了添加用户、删除用户、返回用户数、根据用户名查找用户、根据索引查找用户这5个方法。
1 package com.silianbo.server; 2 3 public class UserLinkList { 4 5 Node root; 6 7 Node pointer; 8 9 int count; 10 11 public UserLinkList() { 12 root = new Node(); 13 root.next = null; 14 pointer = null; 15 count = 0; 16 } 17 18 public void addUser(Node n) { 19 pointer = root; 20 while (pointer.next != null) { 21 pointer = pointer.next; 22 } 23 pointer.next = n; 24 n.next = null; 25 count++; 26 } 27 28 public void delUser(Node n) { 29 pointer = root; 30 while (pointer.next != null) { 31 if (pointer.next == n) { 32 pointer.next = n.next; 33 count--; 34 break; 35 } 36 pointer = pointer.next; 37 } 38 } 39 40 public int getCount() { 41 return count; 42 } 43 44 public Node findUser(String username) { 45 if (count == 0) 46 return null; 47 pointer = root; 48 while (pointer.next != null) { 49 pointer = pointer.next; 50 if (pointer.username.equalsIgnoreCase(username)) { 51 return pointer; 52 } 53 } 54 return null; 55 } 56 57 public Node findUser(int index) { 58 if (count == 0) { 59 return null; 60 } 61 if (index < 0) { 62 return null; 63 } 64 pointer = root; 65 int i = 0; 66 while (i < index + 1) { 67 if (pointer.next != null) { 68 pointer = pointer.next; 69 } else { 70 return null; 71 } 72 i++; 73 } 74 return pointer; 75 } 76 }
Node.java
用户链表的节点类,定义了链表中的用户。该类与前面所讲的链表节点Node类的功能相当
1 package com.silianbo.server; 2 3 import java.net.*; 4 import java.io.*; 5 6 public class Node { 7 8 String username = null; 9 10 Socket socket = null; 11 12 ObjectOutputStream output = null; 13 14 ObjectInputStream input = null; 15 16 Node next = null; 17 }