基于java网络聊天室--服务器端

服务器端:

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 + "端口侦听...
");
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("服务端已经关闭
");
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() + "
";
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 + " 上线" + "
");
47                 textfield.setText("在线用户" + userLinkList.getCount() + "人
");
48                 recvThread = new ServerReceive(textarea, textfield, combobox, client, userLinkList);
49                 recvThread.start();
50             } catch (IOException | ClassNotFoundException e) {
51             }
52         }
53     }
54 }
View Code

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 + "
";
 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 + " 下线
";
 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() + "人
");
 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 += '
';
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 }
View Code

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 }
View Code

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)。
"+
48             "2、点击 启动服务 按钮便可在指定的端口启动服务。
"+
49             "3、选择需要接受消息的用户,在消息栏中写入消息,之后便可发送消息。
"+
50             "4、信息状态栏中显示服务器当前的启动与停止状态、"+
51             "用户发送的消息和
      服务器端发送的系统消息。");
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 }
View Code

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 }
View Code

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 }
View Code
原文地址:https://www.cnblogs.com/silianbo/p/4638532.html