基于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 + "端口侦听...\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 }

时间: 2024-11-05 16:42:43

基于java网络聊天室--服务器端的相关文章

基于java网络聊天室---前言

很久之前做的一个东西,现在拿出来整理一下放在自己的博客中! 一. 设计目的 随着人互联网的发展,人和人之间的沟通方式也越来越便捷和多样化,在线聊天工具已经成为人们生活中够通不可缺少的部分,在学习完 java网络编程课程,如果能开发一款属于自己的聊天工具,和好友进行私密对话,则是一件令人兴奋的事.同时,安全可靠的TCP这两种 通信协议,是非常重要的内容,值得研究. 二. 设计内容 本聊天室程序基于C/S模式,聊天室共分为服务器端和客户端两部分,服务器端程序主要负责侦听客户端发来的消息,客户端需登陆

基于java网络聊天室--客户端

ChatClient.java 包含名为ChatClient的public类,其主要功能为定义客户端的界面,添加时间监听与事件处理.该类定义了Connect()与DisConnect()方法实现与客户端的连接与断开连接.当登陆到指定的服务器时,调用ClientReceive类实现消息收发,同时该类还定义了SendMessaga()方法来其他用户发送带有表情的消息或悄悄话. 1 /* 2 * To change this license header, choose License Headers

基于java网络聊天室--截图实现

package com.silianbo; /* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ import java.awt.BorderLayout; import java.awt.C

基于java的聊天室/群发控制台程序

java聊天室 1.概述 基于tcp协议的,由一个服务器和多个客户端组成,一个客户端发送消息,其他所有客户端都能接收到消息.在服务器端设置一个线程监听客户端发来的请求(消息),并且向所有的客户端响应.每个客户端也有一个线程用来接收服务器端的请求. 2.代码如下 public class Client { public static void main(String[] args) throws IOException { //创建套接字 Socket socket = new Socket("l

基于linux的TCP网络聊天室设计与实现

利用Linux实现基于TCP模式的网络聊天程序 主要完成的两大组成部分为:服务器和客户端. 服务器程序主要负责监听客户端发来的消息. 客户端需要登录到服务器端才可以实现正常的聊天功能.该程序是利用进程以及共享内存来实现群发送消息的. 以下简单分析一下服务器端和客户端两个方面所要完成的任务. 服务器的主要功能如下: 在特定的端口上进行监听,等待客户端的连接. 用户可以配置服务器端的监听端口. 向连接的客户端发送登录成功信息. 向已经连接到服务器的客户端的用户发送系统消息. 使用TCP多线程并发服务

基于SSH的聊天室

随网络聊天室是用户比较喜欢的一种WEB应用程序,借助聊天室,用户可以及时互通信息,交流思想.本系统主要采用了基于B/S(Browser/Server,即浏览器/服务器)模式开发的简易聊天室系统.本系统主要是采用了S2SH技术和JSP技术开发的动态网站.系统开发主要包括前台页面设计.功能设计和后台数据处理设计(即发言区管理和用户管理). 本系统采用了MYECLIPSE8.5作为开发工具,后台数据库采用了MYSQL数据库设计,利用JAVA的框架技术S2SH和后台数据处理.利用TOMCAT6.0以上的

网络聊天室

1网络聊天室项目描写叙述 1.1功能描写叙述 MyQQv1採用C/S模式,构建网络聊天室,详细实现功能: A.能显示在线用户列表 B.能在聊天室里进行群聊天 C.能指定用户进行私聊 D.某用户下线.其它用户能接到提示 1.2所需技术 MFC,Socket套接字,TCP/IP协议.动态数组,CString字符串拼接与拆分 2网络聊天室执行流程图 2.1server执行流程图 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fo

java swing聊天室代码

原文:java swing聊天室代码 源代码下载地址:http://www.zuidaima.com/share/1550463525358592.htm 真正的java聊天室代码,实现简单,阅读方便,原理简单! 先启动server.ServerMain的效果如下: 再启动client.ClientMain的效果如下: 注册界面: 群聊界面: 已注册用户列表: 多个账号群聊界面: 多个账号群聊界面2:

Java NIO示例:多人网络聊天室

一个多客户端聊天室,支持多客户端聊天,有如下功能: 功能1: 客户端通过Java NIO连接到服务端,支持多客户端的连接 功能2:客户端初次连接时,服务端提示输入昵称,如果昵称已经有人使用,提示重新输入,如果昵称唯一,则登录成功,之后发送消息都需要按照规定格式带着昵称发送消息 功能3:客户端登录后,发送已经设置好的欢迎信息和在线人数给客户端,并且通知其他客户端该客户端上线 功能4:服务器收到已登录客户端输入内容,转发至其他登录客户端. 功能5 TODO:客户端下线检测  方案是:客户端在线的时候