聊天室(Java实现)

 

功能:

  登录

    若用户账号不存在,弹出错误

    若用户密码错误,弹出错误

    若用户账号已在线,弹出错误

      

      

      

  注册

    若用户已注册,弹出错误

         

        

  聊天室

    多人聊天,类似QQ里的群。

    点击右侧的在线用户,可进行一对一聊天。 

      

  一对一聊天

    在聊天室中点击在线用户可进入此窗口。

    发送消息后,对方会收到消息,并弹出一对一聊天窗口 。

      


说明:

    服务端的IP和端口固定。(代码中使用127.0.0.1作为服务端的IP)

    客户端通过该IP和端口访问服务器。

    客户端向服务器发送消息,服务器根据消息做出不同的处理,并可能向其他客户端发送消息。

    每个客户端都有一个客户端server进程,以接收服务端发来的消息。

    初始化客户端时,启动客户端server进程,监听任意一个可用端口。用户登录时,将本地账户、密码、本地的server进程端口发给服务端,服务端检验用户合法性,若合 法,则更新该账户的IP地址和端口。以后服务端即可向该IP发送消息。


代码:

   项目工程结构:

    

Server

 1 package chatroomutil;
 2 
 3 import java.io.BufferedReader;
 4 import java.io.IOException;
 5 import java.io.PrintWriter;
 6 import java.net.ServerSocket;
 7 import java.net.Socket;
 8 
 9 public abstract class Server {
10     protected ServerSocket sSocket;
11     public Server() {
12     }
13     protected int listen() {
14         while (true) {
15             Socket ots = null;
16             try {
17                 ots = sSocket.accept();
18             } catch (IOException e) {
19                 ChatRoomUtil.showErrorBox("服务器Accept错误");
20                 System.exit(-1);
21             }
22             Thread hThread = new Thread(new handleThread(ots));
23             hThread.start();
24         }
25     }
26     // 处理消息的进程 的内部类
27     class handleThread implements Runnable {
28         Socket ots;
29         handleThread(Socket ots) {
30             this.ots = ots;
31         }
32         @Override
33         public void run() {
34             handleMessage(ots);
35         }
36     };
37     protected abstract String handle(Socket ots,String rMessage);//处理函数,输入收到的消息,返回要发送的消息
38     private String handleMessage(Socket ots) {
39         StringBuffer buffer=new StringBuffer();
40         BufferedReader reader=ChatRoomUtil.getMsgFromSocket(ots,buffer);//获取消息
41         String rMessage = buffer.toString();
42         String message=handle(ots,rMessage);//处理消息
43         PrintWriter writer=ChatRoomUtil.putMesgToSocket(ots, message);//发送消息
44         ChatRoomUtil.closeSocket(ots,reader,writer);//关闭
45         return null;
46     }
47 }

 ChatRoomUtil

 1 package chatroomutil;
 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 javax.swing.JOptionPane;
 8 
 9 public class ChatRoomUtil {
10     public static String showErrorBox(String message) {//显示错误信息对话框
11         JOptionPane.showMessageDialog(null, message, "错误",
12                 JOptionPane.ERROR_MESSAGE);
13         return message;
14     }
15     //获取消息
16     public static BufferedReader getMsgFromSocket(Socket socket,StringBuffer buffer){
17         BufferedReader reader = null;
18         try {
19             reader = new BufferedReader(
20                     new InputStreamReader(socket.getInputStream()));
21         } catch (IOException e) {
22             ChatRoomUtil.showErrorBox("获取Socket输入流错误");
23             System.exit(-1);
24         }
25         try {
26             String line = "";
27             while ((line = reader.readLine()) != null) {
28                 buffer.append(line + "\n");
29             }
30             buffer.deleteCharAt(buffer.length()-1);//去掉最后一个回车符
31         } catch (IOException e) {
32             ChatRoomUtil.showErrorBox("读取Socket输入流错误");
33             System.exit(-1);
34         }
35         try {
36             socket.shutdownInput();
37         } catch (IOException e) {
38             ChatRoomUtil.showErrorBox("关闭Socket输入时发生错误");
39             System.exit(-1);
40         }
41         return reader; 
42     }
43     //发送消息
44     public static PrintWriter putMesgToSocket(Socket socket,String message){
45         PrintWriter writer = null;
46         try {
47             writer = new PrintWriter(socket.getOutputStream());
48         } catch (IOException e) {
49             ChatRoomUtil.showErrorBox("获取Socket输出流错误");
50             System.exit(-1);
51         }
52         writer.println(message);
53         writer.flush();
54         try {
55             socket.shutdownOutput();
56         } catch (IOException e1) {
57             ChatRoomUtil.showErrorBox("关闭Socket输出时发生错误");
58             System.exit(-1);
59         }
60         return writer;
61     }
62     //关闭socket、输入流、输出流
63     public static void closeSocket(Socket socket,BufferedReader reader,PrintWriter writer ){
64         try {
65             reader.close();
66         } catch (IOException e) {
67             ChatRoomUtil.showErrorBox("关闭Scoket输入流时发生错误");
68             System.exit(-1);
69         }
70         writer.close();
71         try {
72             socket.close();
73         } catch (IOException e) {
74             ChatRoomUtil.showErrorBox("关闭Scoket输出流时发生错误");
75             System.exit(-1);
76         }
77     }
78 }

 ServerServer

  1 package chatroomserver;
  2 import java.io.BufferedReader;
  3 import java.io.FileNotFoundException;
  4 import java.io.FileReader;
  5 import java.io.IOException;
  6 import java.io.RandomAccessFile;
  7 import java.net.ServerSocket;
  8 import java.net.Socket;
  9 import java.util.Enumeration;
 10 import java.util.Hashtable;
 11 import chatroomsend.Send;
 12 import chatroomutil.ChatRoomUtil;
 13 import chatroomutil.Server;
 14 
 15 public class ServerServer extends Server {
 16     Hashtable<String, User> onlineTable = new Hashtable<String, User>();// 在线用户集合
 17     Hashtable<String, User> offlineTable = new Hashtable<String, User>();// 离线用户集合
 18     // 用户内部类
 19     class User {
 20         String id;
 21         String pwd;
 22         String IP;
 23         int port;
 24         User(String id, String pwd) {
 25             this.id = id;
 26             this.pwd = pwd;
 27         }
 28     }
 29     // 发送进程内部类
 30     class sendThread implements Runnable {
 31         String mesg;
 32         String IP;
 33         int port;
 34         sendThread(String IP, int port, String mesg) {
 35             this.IP = IP;
 36             this.port = port;
 37             this.mesg = mesg;
 38         }
 39         @Override
 40         public void run() {
 41             Send sendClient = new Send();
 42             sendClient.connect(IP, port, 1000);
 43             sendClient.send(mesg);
 44         }
 45     };
 46     public ServerServer(int port) throws IOException {
 47         init(port);
 48         initUsers();
 49         listen();
 50     }
 51     private int init(int port) throws IOException {
 52         try {
 53             sSocket = new ServerSocket(port);//绑定指定端口
 54         } catch (IOException e) {
 55             ChatRoomUtil.showErrorBox("服务器初始化失败,无法绑定端口。");
 56             System.exit(-1);
 57         }
 58         return port;
 59     }
 60     private int initUsers() {//读取Users文件,初始化offlineTable
 61         BufferedReader reader = null;
 62         try {
 63             reader = new BufferedReader(new FileReader("Users.txt"));
 64         } catch (FileNotFoundException e1) {
 65             ChatRoomUtil.showErrorBox("无法找到User文件");
 66             System.exit(-1);
 67         }
 68         String line;
 69         String[] fa;
 70         try {
 71             while ((line = reader.readLine()) != null) {
 72                 fa = line.split(":", 2);
 73                 User f = new User(fa[0], fa[1]);
 74                 offlineTable.put(fa[0], f);
 75             }
 76             reader.close();
 77         } catch (IOException e) {
 78             ChatRoomUtil.showErrorBox("读取User文件错误");
 79             System.exit(-1);
 80         }
 81         return 0;
 82     }
 83     private int saveNewUser(String id, String pwd) {//将新用户写入Users文件最后
 84         try {
 85             RandomAccessFile file = new RandomAccessFile("Users.txt", "rw");
 86             file.seek(file.length());
 87             file.writeBytes(id + ":" + pwd + "\r\n");
 88             file.close();
 89         } catch (FileNotFoundException e) {
 90             ChatRoomUtil.showErrorBox("写入User文件错误");
 91             System.exit(-1);
 92         } catch (IOException e) {
 93             ChatRoomUtil.showErrorBox("写入User文件错误");
 94             System.exit(-1);
 95         }
 96         return 0;
 97     }
 98     String loginCheck(String id, String pwd, String IP, int port) {//检查登录用户的合法性
 99         System.out.println("logi check");
100         if (onlineTable.containsKey(id))
101             return "alreadyonline";//该用户已在线
102         User f = offlineTable.get(id);
103         if (f == null)
104             return "nothisid";//无此用户
105         if (f.pwd.compareTo(pwd) == 0) {
106             oneUserOnline(id, IP, port);
107             sendOnlinesToNewOnlineUser(id, IP, port);
108             sendNewOnlineUserToOnlines(id);
109             return "yes";//合法
110         } else {
111             return "wrong";//密码错误
112         }
113     }
114     int oneUserOnline(String id, String IP, int port) {//一个新用户上线
115         User f = offlineTable.get(id);
116         offlineTable.remove(id);
117         onlineTable.put(id, f);
118         f.IP = IP;
119         f.port = port;
120         return 0;
121     }
122     int sendNewOnlineUserToOnlines(String id) {//给所有在线用户发送新上线的用户的id
123         Enumeration<User> fs = onlineTable.elements();
124         while (fs.hasMoreElements()) {
125             User f = fs.nextElement();
126             if (f.id.compareTo(id) != 0) {
127                 Thread hThread = new Thread(
128                         new sendThread(f.IP, f.port, "newf" + id));
129                 hThread.start();
130             }
131         }
132         return 0;
133     }
134     int sendMesg(String mesg) {//向所有在线用户转发一条消息
135         Enumeration<User> fs = onlineTable.elements();
136         while (fs.hasMoreElements()) {
137             User f = fs.nextElement();
138             Thread hThread = new Thread(
139                     new sendThread(f.IP, f.port, "mesg" + mesg));
140             hThread.start();
141         }
142         return 0;
143     }
144     int sendChat(String id, String mesg) {//向一个用户发送一条一对一聊天的消息
145         User f = onlineTable.get(id);
146         Thread hThread = new Thread(
147                 new sendThread(f.IP, f.port, "chat" + mesg));
148         hThread.start();
149         return 0;
150     }
151     String newRegisUser(String id, String pwd) {//有新注册的用户
152         if (onlineTable.containsKey(id) || offlineTable.containsKey(id)) {
153             return "no";
154         }
155         offlineTable.put(id, new User(id, pwd));
156         saveNewUser(id, pwd);
157         return "yes";
158     }
159     int sendOnlinesToNewOnlineUser(String id, String IP, int port) {//给新上线的用户发送所有已在线用户的id
160         if (onlineTable.isEmpty() || onlineTable.size() == 1) {
161             return 0;
162         }
163         StringBuffer strBuf = new StringBuffer();
164         Enumeration<User> fs = onlineTable.elements();
165         while (fs.hasMoreElements()) {
166             User f = fs.nextElement();
167             if (f.id.compareTo(id) != 0) {
168                 strBuf.append(f.id);
169                 strBuf.append(";");
170             }
171         }
172         String str = strBuf.toString();
173         Thread hThread = new Thread(new sendThread(IP, port, "newf" + str));
174         hThread.start();
175         return 0;
176     }
177     int oneUserOffline(String id) {//有一个用户下线,将其下线消息发送给所有在线用户
178         Enumeration<User> fs = onlineTable.elements();
179         while (fs.hasMoreElements()) {
180             User f = fs.nextElement();
181             if (f.id.compareTo(id) == 0) {
182                 onlineTable.remove(id);
183                 offlineTable.put(id, f);
184             } else {
185                 Thread hThread = new Thread(
186                         new sendThread(f.IP, f.port, "offl" + id));
187                 hThread.start();
188             }
189         }
190         return 0;
191     }
192     protected  String handle(Socket ots,String rMessage){
193         System.out.println("handle");
194         if (rMessage.startsWith("regi")) {//注册
195             rMessage = rMessage.substring("regi".length());
196             String id = rMessage.substring(0, rMessage.indexOf(','));
197             String pwd = rMessage.substring(rMessage.indexOf(',') + 1);
198             return newRegisUser(id, pwd);
199         }
200         if (rMessage.startsWith("logi")) {//登录
201             System.out.println("logi");
202             rMessage = rMessage.substring("logi".length());
203             String id = rMessage.substring(0, rMessage.indexOf(','));
204             String pwd = rMessage.substring(rMessage.indexOf(',') + 1,
205                     rMessage.lastIndexOf(','));
206             String portstr = rMessage.substring(rMessage.lastIndexOf(',') + 1);
207             int port = new Integer(portstr);
208             String IP = ots.getInetAddress().getHostAddress();
209             return loginCheck(id, pwd, IP, port);
210         }
211         if (rMessage.startsWith("mesg")) {//聊天室消息
212             String mesg = rMessage.substring(("mesg").length());
213             sendMesg(mesg);
214             return "getm";
215         }
216         if (rMessage.startsWith("chat")) {//一对一消息
217             String chat = rMessage.substring(("chat").length());
218             String id = chat.substring(0, chat.indexOf(':'));
219             String mesg = chat.substring(chat.indexOf(':') + 1);
220             sendChat(id, mesg);
221             return "getm";
222         }
223         if (rMessage.startsWith("offl")) {//下线
224             String id = rMessage.substring(("offl").length());
225             oneUserOffline(id);
226             return "getm";
227         }
228         return "getm";
229     }
230 
231     public static void main(String[] args) {
232         try {
233             new ServerServer(65142);
234         } catch (IOException e) {
235             e.printStackTrace();
236         }
237     }
238 }

 Send

 1 package chatroomsend;
 2 import java.io.BufferedReader;
 3 import java.io.IOException;
 4 import java.io.PrintWriter;
 5 import java.net.InetSocketAddress;
 6 import java.net.Socket;
 7 import chatroomutil.ChatRoomUtil;
 8 
 9 public class Send {
10     Socket socket;
11     public Send() {
12         super();
13         socket = new Socket();
14     }
15     public int connect(String IP, int port, int timeout) {//连接
16         try {
17             socket.connect(new InetSocketAddress(IP, port), timeout);
18         } catch (IOException e) {
19             return -1;
20         }
21         return 0;
22     }
23     public String send(String message) {
24         PrintWriter writer=ChatRoomUtil.putMesgToSocket(socket, message);
25         StringBuffer buffer=new StringBuffer();
26         BufferedReader reader=ChatRoomUtil.getMsgFromSocket(socket,buffer);
27         String rMessage = buffer.toString();
28         ChatRoomUtil.closeSocket(socket,reader,writer);
29         return rMessage;
30     }
31 }

 LoginBox

  1 package chatroomclient;
  2 import java.awt.*;
  3 import java.awt.event.ActionEvent;
  4 import java.awt.event.ActionListener;
  5 import java.awt.event.MouseEvent;
  6 import java.awt.event.MouseListener;
  7 import java.io.IOException;
  8 import javax.swing.*;
  9 import chatroomsend.Send;
 10 import chatroomutil.ChatRoomUtil;
 11 
 12 public class LoginBox extends JFrame implements ActionListener, MouseListener {
 13     private static final long serialVersionUID = -329711894663212488L;
 14     ClientServer myServer;
 15     String serverIP;
 16     int serverPort;
 17     JLabel l_account = new JLabel();
 18     JLabel l_password = new JLabel();
 19     JLabel l_regist = new JLabel();
 20     JTextField j_account = new JTextField();
 21     JPasswordField j_password = new JPasswordField();
 22     JButton submit = new JButton();
 23     JButton cancel = new JButton();
 24     JLabel clearAccount = new JLabel();
 25     JLabel clearPassword = new JLabel();
 26     public LoginBox(String ip, int port) {
 27         super("登录");
 28         try {
 29             myServer = new ClientServer(serverIP, serverPort);
 30             Thread myServerThread = new Thread(myServer);
 31             myServerThread.start();
 32         } catch (IOException e) {
 33             ChatRoomUtil.showErrorBox("服务器进程初始化失败,无法绑定端口。");
 34             System.exit(-1);
 35         }
 36         serverIP = ip;
 37         serverPort = port;
 38         setLayout(null);
 39         l_account.setVisible(true);
 40         l_account.setBounds(80, 40, 50, 30);
 41         l_account.setText("账号:");
 42         l_password.setVisible(true);
 43         l_password.setBounds(80, 80, 50, 30);
 44         l_password.setText("密码:");
 45         j_account.setBounds(130, 40, 150, 30);
 46         j_password.setBounds(130, 80, 150, 30);
 47         clearAccount.setBounds(280, 42, 26, 26);
 48         clearPassword.setBounds(280, 82, 26, 26);
 49         submit.setBounds(100, 130, 80, 30);
 50         submit.setText("登录");
 51         cancel.setText("取消");
 52         clearAccount.setText("X");
 53         clearPassword.setText("X");
 54         clearAccount.setOpaque(true);
 55         clearPassword.setOpaque(true);
 56         clearAccount.setBackground(Color.LIGHT_GRAY);
 57         clearPassword.setBackground(Color.LIGHT_GRAY);
 58         clearAccount.setHorizontalAlignment(JLabel.CENTER);
 59         clearPassword.setHorizontalAlignment(JLabel.CENTER);
 60         submit.setBackground(Color.LIGHT_GRAY);
 61         cancel.setBackground(Color.LIGHT_GRAY);
 62         submit.addActionListener(this);
 63         cancel.addActionListener(this);
 64         cancel.setBounds(190, 130, 80, 30);
 65         l_regist.setBounds(270, 200, 70, 30);
 66         l_regist.setText("没有账号?");
 67         this.add(l_account);
 68         this.add(l_password);
 69         this.add(j_account);
 70         this.add(j_password);
 71         this.add(submit);
 72         this.add(cancel);
 73         this.add(l_regist);
 74         this.add(clearAccount);
 75         this.add(clearPassword);
 76         setBounds(480, 240, 370, 270);
 77         setVisible(true);
 78         setResizable(false);
 79         this.setDefaultCloseOperation(EXIT_ON_CLOSE);
 80         validate();
 81         l_regist.addMouseListener(this);
 82         clearAccount.addMouseListener(this);
 83         clearPassword.addMouseListener(this);
 84     }
 85     String checkPwd(String id, String pwd) {
 86         Send sendClient = new Send();
 87         sendClient.connect(serverIP, serverPort, 1000);
 88         String ret= sendClient
 89                 .send("logi" + id + "," + pwd + "," + myServer.getMyServerPort());
 90         if (ret.compareTo("yes") == 0) {
 91             myServer.chatRoom = new ChatRoom(id, serverIP, serverPort);
 92             dispose();
 93         } else if (ret.compareTo("wrong") == 0) {
 94             ChatRoomUtil.showErrorBox("登录失败,密码有误。");
 95         } else if (ret.compareTo("alreadyonline") == 0) {
 96             ChatRoomUtil.showErrorBox("登录失败,该账号已在线");
 97         } else if (ret.compareTo("nothisid") == 0) {
 98             ChatRoomUtil.showErrorBox("登录失败,账号不存在。");
 99             new RegisBox(serverIP, serverPort,
100                     myServer.getMyServerPort());
101         }
102         return ret;
103     }
104     @Override
105     public void actionPerformed(ActionEvent e) {
106         Object t = e.getSource();
107         if (e.getSource().getClass() == JButton.class) {
108             JButton button = (JButton) (t);
109             if (button.getText().compareTo("登录") == 0) {
110                 String id = j_account.getText();
111                 String pwd = String.valueOf(j_password.getPassword());
112                 if (id.compareTo("") == 0 || pwd.compareTo("") == 0) {
113                     ChatRoomUtil.showErrorBox("账号与密码均不能为空");
114                     return;
115                 }
116                 checkPwd(id, pwd);
117             }
118             if (button.getText().compareTo("取消") == 0) {
119                 dispose();
120                 System.exit(0);
121             }
122         }
123     }
124     @Override
125     public void mouseClicked(MouseEvent e) {
126         if (e.getSource().equals(l_regist)) {
127             new RegisBox(serverIP, serverPort,
128                     myServer.getMyServerPort());
129         }
130         if (e.getSource().equals(clearAccount)) {
131             j_account.setText("");
132         }
133         if (e.getSource().equals(clearPassword)) {
134             j_password.setText("");
135         }
136     }
137     @Override
138     public void mousePressed(MouseEvent e) {
139     }
140     @Override
141     public void mouseReleased(MouseEvent e) {
142     }
143 
144     @Override
145     public void mouseEntered(MouseEvent e) {
146         Object x = e.getSource();
147         if (x.equals(l_regist)) {
148             JLabel l = (JLabel) x;
149             l.setForeground(Color.blue);
150         }
151         if (x.equals(clearAccount) || x.equals(clearPassword)) {
152             JLabel l = (JLabel) x;
153             l.setBackground(Color.GRAY);
154         }
155     }
156 
157     @Override
158     public void mouseExited(MouseEvent e) {
159         Object x = e.getSource();
160         if (x.equals(l_regist)) {
161             JLabel l = (JLabel) x;
162             l.setForeground(Color.BLACK);
163         }
164         if (x.equals(clearAccount) || x.equals(clearPassword)) {
165             JLabel l = (JLabel) x;
166             l.setBackground(Color.LIGHT_GRAY);
167         }
168     }
169     public static void main(String[] args) {
170         String serverIP = "127.0.0.1";
171         int serverPort = 65142;
172         new LoginBox(serverIP, serverPort);
173     }
174 }

 RegisBox

  1 package chatroomclient;
  2 import java.awt.*;
  3 import java.awt.event.ActionEvent;
  4 import java.awt.event.ActionListener;
  5 import javax.swing.*;
  6 import chatroomsend.Send;
  7 import chatroomutil.ChatRoomUtil;
  8 public class RegisBox extends JFrame implements ActionListener {
  9     private static final long serialVersionUID = 5795626909275119718L;
 10     String serverIP;
 11     int serverPort;
 12     int myServerPort;
 13     JLabel id_label = new JLabel();
 14     JLabel pwd_label = new JLabel();
 15     JLabel pwdCheck_label = new JLabel();
 16     JLabel num_label = new JLabel();
 17     JLabel firstName_label = new JLabel();
 18     JLabel lastName_label = new JLabel();
 19     JLabel age_label = new JLabel();
 20     JLabel sex_label = new JLabel();
 21     JTextField id_text = new JTextField();
 22     JPasswordField pwd_text = new JPasswordField();
 23     JPasswordField pwdCheck_text = new JPasswordField();
 24     JTextField num_text = new JTextField();
 25     JTextField firstName_text = new JTextField();
 26     JTextField lastName_text = new JTextField();
 27     JTextField age_text = new JTextField();
 28     JComboBox sex_box = new JComboBox();
 29     JButton cancel = new JButton();
 30     JButton regis = new JButton();
 31     public RegisBox(String serverIP, int serverPort, int myServerPort) {
 32         super();
 33         this.serverIP = serverIP;
 34         this.serverPort = serverPort;
 35         this.myServerPort = myServerPort;
 36         setLayout(null);
 37         setTitle("注册");
 38         id_label.setBounds(60, 23, 50, 20);
 39         pwd_label.setBounds(60, 53, 50, 20);
 40         pwdCheck_label.setBounds(50, 83, 70, 20);
 41         num_label.setBounds(60, 113, 50, 20);
 42         firstName_label.setBounds(60, 143, 50, 20);
 43         lastName_label.setBounds(60, 173, 50, 20);
 44         age_label.setBounds(60, 203, 50, 20);
 45         sex_label.setBounds(60, 233, 50, 20);
 46         id_text.setBounds(130, 20, 200, 26);
 47         pwd_text.setBounds(130, 50, 200, 26);
 48         pwdCheck_text.setBounds(130, 80, 200, 26);
 49         num_text.setBounds(130, 110, 200, 26);
 50         firstName_text.setBounds(130, 140, 200, 26);
 51         lastName_text.setBounds(130, 170, 200, 26);
 52         age_text.setBounds(130, 200, 200, 26);
 53         sex_box.setBounds(130, 230, 200, 26);
 54         regis.setBounds(190, 270, 70, 30);
 55         cancel.setBounds(270, 270, 70, 30);
 56         id_label.setText("账号");
 57         pwd_label.setText("密码");
 58         pwdCheck_label.setText("密码确认");
 59         num_label.setText("编号");
 60         firstName_label.setText("名");
 61         lastName_label.setText("姓");
 62         age_label.setText("年龄");
 63         sex_label.setText("性别");
 64         sex_box.addItem("男");
 65         sex_box.addItem("女");
 66         regis.setText("提交");
 67         cancel.setText("取消");
 68         regis.setBackground(Color.LIGHT_GRAY);
 69         cancel.setBackground(Color.LIGHT_GRAY);
 70         sex_box.setBackground(Color.LIGHT_GRAY);
 71         regis.addActionListener(this);
 72         cancel.addActionListener(this);
 73         this.add(id_label);
 74         this.add(pwd_label);
 75         this.add(pwdCheck_label);
 76         this.add(num_label);
 77         this.add(firstName_label);
 78         this.add(lastName_label);
 79         this.add(age_label);
 80         this.add(sex_label);
 81         this.add(id_text);
 82         this.add(pwd_text);
 83         this.add(pwdCheck_text);
 84         this.add(num_text);
 85         this.add(firstName_text);
 86         this.add(lastName_text);
 87         this.add(age_text);
 88         this.add(sex_box);
 89         this.add(regis);
 90         this.add(cancel);
 91         setBounds(200, 200, 500, 400);
 92         validate();
 93         setResizable(false);
 94         setVisible(true);
 95     }
 96     boolean regis(String serverIP, int serverPort, String id, String pwd,
 97             int myServerPort) {
 98         Send sendClient = new Send();
 99         sendClient.connect(serverIP, serverPort, 1000);
100         if (sendClient.send("regi" + id + "," + pwd).compareTo("yes") == 0) {
101             return true;
102         }
103         return false;
104     }
105     boolean check() {
106         String id = id_text.getText();
107         String pwd = String.valueOf(pwd_text.getPassword());
108         String pwdc = String.valueOf(pwdCheck_text.getPassword());
109         String fName = firstName_text.getText();
110         String lName = lastName_text.getText();
111         String age = age_text.getText();
112         String num = num_text.getText();
113         String sex = sex_box.getSelectedItem().toString();
114         if (id.compareTo("") == 0) {
115             ChatRoomUtil.showErrorBox("账号不能为空");
116             return false;
117         }
118         if (pwd.compareTo("") == 0) {
119             ChatRoomUtil.showErrorBox("密码不能为空");
120             return false;
121         }
122         if (pwdc.compareTo("") == 0) {
123             ChatRoomUtil.showErrorBox("请确认密码");
124             return false;
125         }
126         if (pwd.compareTo(pwdc) != 0) {
127             ChatRoomUtil.showErrorBox("两次输入的密码不符");
128             return false;
129         }
130         if (num.compareTo("") == 0) {
131             ChatRoomUtil.showErrorBox("编号不能为空");
132             return false;
133         }
134         if (fName.compareTo("") == 0) {
135             ChatRoomUtil.showErrorBox("名不能为空");
136             return false;
137         }
138         if (lName.compareTo("") == 0) {
139             ChatRoomUtil.showErrorBox("姓不能为空");
140             return false;
141         }
142         if (age.compareTo("") == 0) {
143             ChatRoomUtil.showErrorBox("年龄不能为空");
144             return false;
145         }
146         if (sex.compareTo("") == 0) {
147             ChatRoomUtil.showErrorBox("性别不能为空");
148             return false;
149         }
150         if (regis(serverIP, serverPort, id, pwd, myServerPort)) {
151             dispose();
152         } else {
153             ChatRoomUtil.showErrorBox("注册失败。该用户已存在");
154             return false;
155         }
156         return true;
157     }
158     @Override
159     public void actionPerformed(ActionEvent e) {
160         Object t = e.getSource();
161         if (e.getSource().getClass() == JButton.class) {
162             JButton button = (JButton) (t);
163             if (button.getText().compareTo("提交") == 0) {
164                 check();
165             }
166             if (button.getText().compareTo("取消") == 0) {
167                 dispose();
168             }
169         }
170     }
171 }

 ClientServer

 1 package chatroomclient;
 2 import java.io.IOException;
 3 import java.net.ServerSocket;
 4 import java.net.Socket;
 5 import chatroomutil.ChatRoomUtil;
 6 import chatroomutil.Server;
 7 
 8 public class ClientServer extends Server implements Runnable {
 9     ChatRoom chatRoom;
10     private int myPort;
11     public ClientServer(String serverIP, int serverPort) throws IOException {
12         super();
13         myPort = init();
14     }
15     int getMyServerPort() {
16         return myPort;
17     }
18     private int createServerSocket(int i) throws IOException {//绑定端口i
19         if (i >= 65536) {
20             ChatRoomUtil.showErrorBox("ClientServer无端口可绑定");
21             System.exit(-1);
22         }
23         try {
24             sSocket = new ServerSocket(i);
25         } catch (IOException e) {
26             return createServerSocket(i + 1);
27         }
28         return i;
29     }
30     private int init() throws IOException {
31         int port = createServerSocket(1025);
32         return port;
33     }
34     @Override
35     protected String handle(Socket ots,String rMessage){
36         String message = "getm";
37         if (rMessage.startsWith("newf")) {
38             while (chatRoom == null) {
39                 try {
40                     Thread.sleep(300);
41                 } catch (InterruptedException e) {
42                     ChatRoomUtil.showErrorBox("ClientServer在Sleep时出错");
43                     System.exit(-1);
44                 }
45             }
46             String ids = rMessage.substring(("newf").length());
47             String[] idArray = ids.split(";");
48             chatRoom.addFriend(idArray);
49         }
50         if (rMessage.startsWith("offl")) {
51             String name = rMessage.substring(("offl").length());
52             chatRoom.removeFriend(name);
53         }
54         if (rMessage.startsWith("mesg")) {
55             String mesg = rMessage.substring(("mesg").length());
56             chatRoom.addRecord(mesg);
57         }
58         if (rMessage.startsWith("chat")) {
59             String chat = rMessage.substring(("chat").length());
60             String id = chat.substring(0, chat.indexOf(':'));
61             String mesg = chat.substring(chat.indexOf(':') + 1);
62             chatRoom.dialogAddRecord(id, mesg);
63         }
64         return message;
65     }
66     @Override
67     public void run() {
68         listen();
69     }
70 }

 ChatRoom

  1 package chatroomclient;
  2 import java.awt.*;
  3 import java.awt.event.ActionEvent;
  4 import java.awt.event.ActionListener;
  5 import java.awt.event.MouseEvent;
  6 import java.awt.event.MouseListener;
  7 import java.awt.event.WindowAdapter;
  8 import java.awt.event.WindowEvent;
  9 import java.util.HashSet;
 10 import java.util.Hashtable;
 11 import java.util.Iterator;
 12 import java.util.TimerTask;
 13 import javax.swing.*;
 14 import javax.swing.event.CaretEvent;
 15 import javax.swing.event.CaretListener;
 16 import chatroomsend.Send;
 17 import chatroomutil.ChatRoomUtil;
 18 
 19 public class ChatRoom extends JFrame implements ActionListener, MouseListener {
 20     private static final long serialVersionUID = -9016166784223701159L;
 21     String myId;
 22     String serverIP;
 23     int serverPort;
 24     JLabel chatRoomLabel = new JLabel();
 25     JLabel onlineLabel = new JLabel();
 26     JTextArea chatArea = new JTextArea();
 27     JPanel onlineArea = new JPanel();
 28     JTextArea sendArea = new JTextArea(5, 20);
 29     JButton sendButton = new JButton();
 30     JScrollPane chatScroll = new JScrollPane(chatArea);
 31     JScrollPane onlineScroll = new JScrollPane(onlineArea);
 32     JScrollPane sendScroll = new JScrollPane(sendArea);
 33     JPanel chatPanel = new JPanel();
 34     JPanel onlinePanel = new JPanel();
 35     JPanel sendPanel = new JPanel();
 36     JPanel chatAndOnlinePanel = new JPanel();
 37     HashSet<String> friends = new HashSet<String>();
 38     Hashtable<String, ChatDialog> chatDialogs = new Hashtable<String, ChatDialog>();
 39     BorderLayout mainLayout = new BorderLayout();
 40     BorderLayout chatLayout = new BorderLayout();
 41     BorderLayout onlineLayout = new BorderLayout();
 42     BorderLayout sendLayout = new BorderLayout();
 43     BorderLayout chatAndOnlineLayout = new BorderLayout();
 44     FlowLayout onlineAreaLayout = new FlowLayout();
 45     public ChatRoom(String id, String serverIP, int port) {
 46         super("聊天室   " + id);
 47         this.myId = id;
 48         this.serverIP = serverIP;
 49         this.serverPort = port;
 50         mainLayout.setVgap(5);
 51         sendLayout.setHgap(10);
 52         chatAndOnlineLayout.setHgap(15);
 53         onlineAreaLayout.setVgap(1);
 54         this.setLayout(mainLayout);
 55         chatPanel.setLayout(chatLayout);
 56         onlinePanel.setLayout(onlineLayout);
 57         sendPanel.setLayout(sendLayout);
 58         chatAndOnlinePanel.setLayout(chatAndOnlineLayout);
 59         chatArea.setLineWrap(true);
 60         sendArea.setLineWrap(true);
 61         onlineArea.setLayout(onlineAreaLayout);
 62         onlineArea.setPreferredSize(new Dimension(130, 200));
 63         sendButton.setText("   发送    ");
 64         sendButton.setBackground(Color.LIGHT_GRAY);
 65         sendButton.addActionListener(this);
 66         onlineLabel.setText("在线好友(点击可开始聊天)");
 67         chatRoomLabel.setText("聊天");
 68         chatArea.setEditable(false);
 69         chatArea.setBackground(new Color(230, 230, 230));
 70         chatPanel.add(chatRoomLabel, BorderLayout.NORTH);
 71         chatPanel.add(chatScroll, BorderLayout.CENTER);
 72         onlinePanel.add(onlineLabel, BorderLayout.NORTH);
 73         onlinePanel.add(onlineScroll, BorderLayout.CENTER);
 74         sendPanel.add(sendScroll, BorderLayout.CENTER);
 75         sendPanel.add(sendButton, BorderLayout.EAST);
 76         chatAndOnlinePanel.add(chatPanel, BorderLayout.CENTER);
 77         chatAndOnlinePanel.add(onlinePanel, BorderLayout.EAST);
 78         this.add(sendPanel, BorderLayout.SOUTH);
 79         this.add(chatAndOnlinePanel, BorderLayout.CENTER);
 80         friends.add(myId);
 81         this.setBounds(200, 200, 600, 650);
 82         setVisible(true);
 83         reFreshOnlineArea();
 84         this.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
 85         this.addWindowListener(new WindowAdapter() {
 86             public void windowClosing(WindowEvent e) {//点击关闭按钮时发送下线消息
 87                 sendOffLine();
 88                 System.exit(0);
 89             }
 90         });
 91         sendArea.addCaretListener(new CaretListener() {
 92             @Override
 93             public void caretUpdate(CaretEvent e) {
 94                 String str = sendArea.getText();
 95                 if (str.length() > 5000) {
 96                     ChatRoomUtil.showErrorBox("字数过多,超出限制。");
 97                 }
 98             }
 99         });
100         new java.util.Timer().schedule(new TimerTask() {//定时刷新界面
101             public void run() {
102                 repaint();
103             }
104         }, 400, 400);
105     }
106     int reFreshOnlineArea() {//刷新当前在线用户
107         int size = friends.size();
108         onlineArea.removeAll();
109         Iterator<String> it = friends.iterator();
110         while (it.hasNext()) {
111             String str = it.next();
112             String id = str;
113             JLabel label = new JLabel(id);
114             label.addMouseListener(this);
115             label.setPreferredSize(new Dimension(130, 20));
116             label.setBackground(Color.GRAY);
117             label.setForeground(Color.WHITE);
118             label.setHorizontalAlignment(JLabel.CENTER);
119             label.setOpaque(true);
120             onlineArea.add(label);
121         }
122         onlineArea.setPreferredSize(new Dimension(130, size * 22));
123         this.repaint();
124         this.validate();
125         return 0;
126     }
127     int sendOffLine() {//发送下线消息
128         Send sendClient = new Send();
129         sendClient.connect(serverIP, serverPort, 1000);
130         sendClient.send("offl" + myId);
131         return 0;
132     }
133     public int addFriend(String[] fs) {//添加上线的用户
134         for (int i = 0; i < fs.length; i++) {
135             friends.add(fs[i]);
136         }
137         reFreshOnlineArea();
138         return 0;
139     }
140     public int removeFriend(String friendID) {//移除一个用户(已下线)
141         friends.remove(friendID);
142         reFreshOnlineArea();
143         return 0;
144     }
145     public int addRecord(String mesg) {//添加聊天记录
146         chatArea.append(mesg + "\n");
147         chatArea.setCaretPosition(chatArea.getText().length());
148         this.validate();
149         return 0;
150     }
151     public int dialogAddRecord(String id, String mesg) {//给一对一聊天增加聊天记录
152         if (chatDialogs.containsKey(id) == false) {
153             chatDialogs.put(id,
154                     new ChatDialog(this, myId, id, serverIP, serverPort));
155         }
156         chatDialogs.get(id).addRecord(mesg);
157         return 0;
158     }
159     int removeDialog(String id) {//移除一对一聊天
160         chatDialogs.remove(id);
161         return 0;
162     }
163     private String sendMessage(String mesg) {//发送群聊消息
164         Send sendClient = new Send();
165         sendClient.connect(serverIP, serverPort, 1000);
166         String getm = sendClient.send("mesg" + myId + ":  \n" + mesg);
167         return getm;
168     }
169     @Override
170     public void actionPerformed(ActionEvent e) {
171         if (e.getSource().getClass() == JButton.class) {
172             sendMessage(sendArea.getText());
173             sendArea.setText("");
174         }
175     }
176     @Override
177     public void mouseClicked(MouseEvent e) {
178         if (e.getSource().getClass() == JLabel.class) {
179             JLabel l = (JLabel) e.getSource();
180             if (l.getText().compareTo(myId) == 0) {
181                 return;
182             }
183             if (chatDialogs.containsKey(l.getText())) {
184                 return;
185             }
186             chatDialogs.put(l.getText(), new ChatDialog(this, myId, l.getText(),
187                     serverIP, serverPort));
188         }
189     }
190     @Override
191     public void mouseEntered(MouseEvent e) {
192         if (e.getSource().getClass() == JLabel.class) {
193             JLabel l = (JLabel) e.getSource();
194             l.setBackground(Color.LIGHT_GRAY);
195             l.setForeground(Color.BLACK);
196         }
197     }
198     @Override
199     public void mouseExited(MouseEvent e) {
200         if (e.getSource().getClass() == JLabel.class) {
201             JLabel l = (JLabel) e.getSource();
202             l.setBackground(Color.GRAY);
203             l.setForeground(Color.WHITE);
204         }
205     }
206     @Override
207     public void mousePressed(MouseEvent e) {
208     }
209     @Override
210     public void mouseReleased(MouseEvent e) {
211     }
212 }

 ChatDialog

  1 package chatroomclient;
  2 import java.awt.*;
  3 import java.awt.event.ActionEvent;
  4 import java.awt.event.ActionListener;
  5 import java.awt.event.WindowAdapter;
  6 import java.awt.event.WindowEvent;
  7 import java.util.HashSet;
  8 import java.util.TimerTask;
  9 import javax.swing.*;
 10 import javax.swing.event.CaretEvent;
 11 import javax.swing.event.CaretListener;
 12 import chatroomsend.Send;
 13 import chatroomutil.ChatRoomUtil;
 14 
 15 public class ChatDialog extends JFrame implements ActionListener {
 16     private static final long serialVersionUID = 1437996471885472344L;
 17     String myId;
 18     String otsId;
 19     String serverIP;
 20     int serverPort;
 21     JLabel chatRoomLabel = new JLabel();
 22     JTextArea chatArea = new JTextArea();
 23     JTextArea sendArea = new JTextArea(5, 20);
 24     JButton sendButton = new JButton();
 25     JScrollPane chatScroll = new JScrollPane(chatArea);
 26     JScrollPane sendScroll = new JScrollPane(sendArea);
 27     JPanel chatPanel = new JPanel();
 28     JPanel sendPanel = new JPanel();
 29     HashSet<String> friends = new HashSet<String>();
 30     BorderLayout mainLayout = new BorderLayout();
 31     BorderLayout chatLayout = new BorderLayout();
 32     BorderLayout sendLayout = new BorderLayout();
 33     ChatRoom chatRoom;
 34     public ChatDialog(final ChatRoom chatRoom, String id, final String otsId,
 35             String serverIP, int port) {
 36         super(id + "与" + otsId + "聊天");
 37         this.chatRoom = chatRoom;
 38         this.myId = id;
 39         this.otsId = otsId;
 40         this.serverIP = serverIP;
 41         this.serverPort = port;
 42         mainLayout.setVgap(5);
 43         sendLayout.setHgap(10);
 44         this.setLayout(mainLayout);
 45         chatPanel.setLayout(chatLayout);
 46         sendPanel.setLayout(sendLayout);
 47         chatArea.setLineWrap(true);
 48         sendArea.setLineWrap(true);
 49         sendButton.setText("   发送    ");
 50         sendButton.setBackground(Color.LIGHT_GRAY);
 51         sendButton.addActionListener(this);
 52         chatRoomLabel.setText("聊天");
 53         chatArea.setEditable(false);
 54         chatArea.setBackground(new Color(230, 230, 230));
 55         chatPanel.add(chatRoomLabel, BorderLayout.NORTH);
 56         chatPanel.add(chatScroll, BorderLayout.CENTER);
 57         sendPanel.add(sendScroll, BorderLayout.CENTER);
 58         sendPanel.add(sendButton, BorderLayout.EAST);
 59         this.add(sendPanel, BorderLayout.SOUTH);
 60         this.add(chatPanel, BorderLayout.CENTER);
 61         this.setBounds(200, 200, 530, 600);
 62         setVisible(true);
 63         this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
 64         sendArea.addCaretListener(new CaretListener() {
 65             @Override
 66             public void caretUpdate(CaretEvent e) {
 67                 String str = sendArea.getText();
 68                 if (str.length() > 5000) {
 69                     ChatRoomUtil.showErrorBox("字数过多,超出限制。");
 70                 }
 71             }
 72         });
 73         this.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
 74         this.addWindowListener(new WindowAdapter() {
 75             public void windowClosing(WindowEvent e) {//关闭窗口后,ChatRoom要移除该对话
 76                 chatRoom.removeDialog(otsId);
 77                 dispose();
 78             }
 79         });
 80         new java.util.Timer().schedule(new TimerTask() {
 81             public void run() {
 82                 repaint();
 83             }
 84         }, 400, 400);
 85     }
 86     public int addRecord(String mesg) {
 87         chatArea.append(mesg + "\n");
 88         chatArea.setCaretPosition(chatArea.getText().length());
 89         this.validate();
 90         return 0;
 91     }
 92     private String sendMessage(String mesg) {
 93         Send sendClient = new Send();
 94         sendClient.connect(serverIP, serverPort, 1000);
 95         String getm = sendClient.send(
 96                 "chat" + otsId + ":" + myId + ":" + myId + ":   \n" + mesg);
 97         addRecord(myId + ":   \n" + mesg);
 98         return getm;
 99     }
100     @Override
101     public void actionPerformed(ActionEvent e) {
102         if (e.getSource().getClass() == JButton.class) {
103             sendMessage(sendArea.getText());
104             sendArea.setText("");
105         }
106     }
107 }

Users.txt

  1 1:1
  2 2:2
  3 3:3
  4 4:4
  5 5:5
  6 6:6
  7 7:7
  8 8:8
  9 9:9
 10 10:10
 11 11:11
 12 12:12
 13 13:13
 14 14:14
 15 15:15
 16 16:16
 17 17:17
 18 18:18
 19 19:19
 20 20:20
 21 21:21
 22 22:22
 23 23:23
 24 24:24
 25 25:25
 26 26:26
 27 27:27
 28 28:28
 29 29:29
 30 30:30
 31 31:31
 32 32:32
 33 33:33
 34 34:34
 35 35:35
 36 36:36
 37 37:37
 38 38:38
 39 39:39
 40 40:40
 41 41:41
 42 42:42
 43 43:43
 44 44:44
 45 45:45
 46 46:46
 47 47:47
 48 48:48
 49 49:49
 50 50:50
 51 51:51
 52 52:52
 53 53:53
 54 54:54
 55 55:55
 56 56:56
 57 57:57
 58 58:58
 59 59:59
 60 60:60
 61 61:61
 62 62:62
 63 63:63
 64 64:64
 65 65:65
 66 66:66
 67 67:67
 68 68:68
 69 69:69
 70 70:70
 71 71:71
 72 72:72
 73 73:73
 74 74:74
 75 75:75
 76 76:76
 77 77:77
 78 78:78
 79 79:79
 80 80:80
 81 81:81
 82 82:82
 83 83:83
 84 84:84
 85 85:85
 86 86:86
 87 87:87
 88 88:88
 89 89:89
 90 90:90
 91 91:91
 92 92:92
 93 93:93
 94 94:94
 95 95:95
 96 96:96
 97 aa:aa
 98 qq:qq
 99 ww:ww
100 ee:ee
101 guochengxin:guochengxin
102 huoda:huoda
103 zhangfa:zhangfa
104 hanyu:hanyu
105 maxuewei:maxuewei
106 lizeyu:lizeyu

End

写于大三下实训期间

随笔写于2016.7.13

原文地址:https://www.cnblogs.com/maxuewei2/p/5665298.html