java实现udp聊天室
2021/5/23 20:28:53
本文主要是介绍java实现udp聊天室,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
运行结果展示
①登陆两个用户,此时还没有创建有聊天室
②创建一个聊天室
③李四聊天被骂,自己也创建一个聊天室
代码:
①登陆:
package com.ljh; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.HashMap; public class AdminLogin extends JFrame { private JFrame frame = new JFrame("登录"); private JPanel c = (JPanel) frame.getContentPane(); private JTextField username = new JTextField(); private JPasswordField password = new JPasswordField(); private JButton ok = new JButton("确定"); private JButton cancel = new JButton("取消"); public static HashMap<String,GroupList> groupListHashMap=new HashMap<String, GroupList>(); //用来存放每个用户的聊天室列表,因为需要动态加入聊天室 public AdminLogin(){ frame.setLocation(800,350); frame.setSize(350,240); c.setLayout(new BorderLayout()); initFrame(); frame.setVisible(true); } private void initFrame() { //顶部 JPanel titlePanel = new JPanel(); titlePanel.setBackground(Color.GRAY); titlePanel.setLayout(new FlowLayout()); titlePanel.add(new JLabel("聊天室登录")); c.add(titlePanel,"North"); //中部表单 JPanel fieldPanel = new JPanel(); fieldPanel.setBackground(Color.lightGray); fieldPanel.setLayout(null); final JLabel l1 = new JLabel("用户名:"); l1.setBounds(50, 30, 50, 20); final JLabel l2 = new JLabel("密 码:"); l2.setBounds(50, 70, 50, 20); fieldPanel.add(l1); fieldPanel.add(l2); username.setBounds(110,30,120,20); password.setBounds(110,70,120,20); username.setText(""); password.setText(""); fieldPanel.add(username); fieldPanel.add(password); c.add(fieldPanel,"Center"); //底部按钮 JPanel buttonPanel = new JPanel(); buttonPanel.setLayout(new GridLayout()); ok.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { String clicentName=username.getText(); GroupList groupList=new GroupList(clicentName); groupListHashMap.put(clicentName,groupList); groupList.showRoom(); //登陆之后显示已经存在的聊天室 } }); ok.setBackground(Color.PINK); cancel.setBackground(Color.pink); buttonPanel.add(cancel); buttonPanel.add(ok); c.add(buttonPanel,"South"); } public static void main(String args[]){ AdminLogin login=new AdminLogin(); ChatServer r = new ChatServer(); r.start(); } }
②聊天室列表;
package com.ljh; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.net.SocketException; import java.util.ArrayList; import java.util.Iterator; import java.util.Set; public class GroupList extends JFrame{ public static int groupNum=0; private static final long serialVersionUID = 1L; JFrame frame = new JFrame("聊天室列表"); JLabel showRoomNumLabel=new JLabel("num1"); //用来显示聊天室的数量 JButton createButton=new JButton("创建聊天室"); String clientName; public GroupList(final String clientName ){ this.clientName=clientName; createButton.setBackground(Color.pink); frame.setTitle("聊天室列表-----用户:"+clientName); //frame.setLayout(null); frame.setSize(800, 500); ImageIcon background = new ImageIcon("E:\\计算机网络\\udp_chat\\src\\main\\resources\\img\\bg.jpg");// 背景图片 JLabel label = new JLabel(background);// 把背景图片显示在一个标签里面 label.setBounds(0, 0, background.getIconWidth(), background.getIconHeight()); JPanel jpanel = (JPanel) frame.getContentPane(); jpanel.setOpaque(false); jpanel.setLayout(null); frame.getLayeredPane().setLayout(null); frame.getLayeredPane().add(label, new Integer(Integer.MIN_VALUE)); frame.setResizable(false); frame.setVisible(true); createButton.setBounds(350,0,100,20); frame.add(createButton); showRoomNumLabel.setBounds(20,3,200,30); frame.add(showRoomNumLabel); frame.show(); createButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { final createFrame create=new createFrame(); create.okCreateButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if(create.createGroupId.getText()!=null){ if(createRoom(create.createGroupId.getText())){ try { new ChatClient(create.createGroupId.getText(),clientName); Iterator iterator= AdminLogin.groupListHashMap.keySet().iterator(); while (iterator.hasNext()){ //遍历每个用户的聊天室列表 GroupList groupList=AdminLogin.groupListHashMap.get(iterator.next()); groupList.addRoom(create.createGroupId.getText()); //每个用户的聊天列表都加上新建的这个聊天列表 } } catch (SocketException e1) { e1.printStackTrace(); } finally { create.createFrame1.setVisible(false); } } } } }); } }); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { Set<String> groups=ChatServer.groups.keySet(); Iterator<String> iterator=groups.iterator(); while(iterator.hasNext()) { //如果聊天室没人,那么该聊天室会被移除 String groupId=iterator.next(); ArrayList<ChatClient> group=ChatServer.groups.get(groupId); if (group.size()==0){ System.out.println(groupId+"会被移除----------------"); removeRoom(groupId); return; } } dispose(); } }); } public void addRoom(final String groupId){ //向用户列表添加聊天室 JButton button=new JButton("<html><body>"+groupId+"<br>点击进入</body></html>"); button.setBackground(Color.lightGray); int row=0; int colunm=0; if(groupNum%3==0){ colunm=3; }else if(groupNum%3==2){ colunm=2; }else colunm=1; row=groupNum/3; if(groupNum%3==0) row--; button.setBounds(25+250*(colunm-1),(10+150)*row+30,200,150); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { try { new ChatClient(groupId,clientName); } catch (SocketException e1) { e1.printStackTrace(); } } }); showRoomNumLabel.setText("当前聊天室数量"+groupNum); frame.add(button); frame.validate(); //初始化比较晚,所以添加组件后必须要刷新才能显示 frame.repaint(); } public boolean createRoom(String groupId){ //这个方法是创建一个不存在的聊天室 if(groupId=="")return false; Set groupsName=ChatServer.groups.keySet(); Iterator iterator=groupsName.iterator(); while (iterator.hasNext()){ if (iterator.next().equals(groupId)){ //如果已经存在这个聊天室id了 return false; } } groupNum++; return true; } public boolean removeRoom(String groupId){ //删除一个聊天室 if(groupNum<=0){ return false; } ChatServer.groups.remove(groupId); Iterator<String> iterator= AdminLogin.groupListHashMap.keySet().iterator(); groupNum--; while (iterator.hasNext()){ String clientName=iterator.next(); GroupList groupList=AdminLogin.groupListHashMap.get(clientName); //获得所有的登陆用户,以便下面更改他们的聊天室显示 groupList.frame.getContentPane().removeAll(); groupList.showRoom(); groupList.frame.validate(); groupList.frame.repaint(); } return true; } public void showRoom(){ if(groupNum<=0){ //如果当前没有聊天室则在相应地方显示 showRoomNumLabel.setText("当前没还有聊天室"); frame.validate(); frame.repaint(); return; } Set groupsName=ChatServer.groups.keySet(); int num=ChatServer.groups.size(); Iterator<String> iterator=groupsName.iterator(); for(int i=1;i<=num+1;i++) { if (iterator.hasNext()) { final String groupId=iterator.next(); JButton button=new JButton("<html><body>"+groupId+"<br>点击进入</body></html>"); button.setBackground(Color.lightGray); int row=0; int colunm=0; if(i%3==0){ colunm=3; }else if(i%3==2){ colunm=2; }else colunm=1; row=i/3; if(i%3==0) row--; button.setBounds(25+250*(colunm-1),(10+150)*row+30,200,150); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { try { new ChatClient(groupId,clientName); } catch (SocketException e1) { e1.printStackTrace(); } } }); frame.setTitle("聊天室列表-----用户:"+clientName); showRoomNumLabel.setText("当前聊天室数量"+groupNum); frame.add(createButton); frame.add(showRoomNumLabel); frame.add(button); frame.validate(); //初始化比较晚,所以添加组件后必须要刷新才能显示 frame.repaint(); } } } }
③客户端
package com.ljh; import javax.swing.*; import java.awt.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.IOException; import java.net.*; import java.util.ArrayList; public class ChatClient extends JFrame { private static final long serialVersionUID = 1L; // 聊天室ID private String groupID; // 客户端用户名 public String clientName; // 客户端套接字 private DatagramSocket msg_send; // 服务端口 private final int PORT = 10000; // 服务器IP地址 private InetAddress ip; // 客户端控件 TextArea tf = new TextArea(8,55); TextArea ta = new TextArea(15,55); JTextArea showClient=new JTextArea(10,23); Button send = new Button("send"); JLabel loginShow=new JLabel(); // 客户端构造器 public ChatClient(final String groupID, String clientName) throws SocketException { super("聊天室:" + groupID + "/" + clientName); this.clientName = clientName; this.groupID = groupID; ta.setBackground(Color.lightGray); send.setBackground(Color.cyan); Panel panel1=new Panel(); Panel panel2=new Panel(); panel1.setLayout(new FlowLayout()); panel2.add(showClient); panel1.add(ta); panel1.add(tf); add("North",loginShow); add("Center",panel1); add("South", send); add("East",showClient); setSize(680, 500); show(); // 聊天相关服务器初始化 init(); try { // 获取输入内容 String content = tf.getText(); // 发送登陆消息 send_login(content); // 清空聊天框 tf.setText(null); } catch (Exception ioe) { System.out.print(ioe.getMessage()); } // 监听器 final ChatClient this_=this; addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { try { String content = tf.getText(); // 发送离线消息消息 send_go(content); ChatServer.leaveGroup(groupID,this_); //将离开的用户从group中删除 // 清空聊天框 tf.setText(null); } catch (Exception ioe) { System.out.print(ioe.getMessage()); } // 关闭消息发送服务 msg_send.close(); // 关闭客户端程序 dispose(); //System.exit(0); } }); } private void init() throws SocketException { ChatServer.logInGroup(groupID, this); try { msg_send = new DatagramSocket(); // 指定消息服务器 try { ip = InetAddress.getByName("127.0.0.1"); } catch (UnknownHostException e) { System.out.println("连接错误"); } } catch (SocketException e) { System.out.println("连接错误"); } } // 消息发送按钮监听 public boolean action(Event evt, Object arg) { if (evt.target.equals(send)) { try { // 获取输入内容 String content = tf.getText(); // 发送聊天消息 send_message(content); // 清空聊天框 tf.setText(null); } catch (Exception ioe) { System.out.print(ioe.getMessage()); } } return true; } // 消息发送 private void send_message(String content) { String message = messageFormat0(content); // 将消息封装成UDP数据包 byte[] buf = message.getBytes(); DatagramPacket packet = new DatagramPacket(buf, buf.length, ip, PORT); try { // 通过UDP协议发送消息 msg_send.send(packet); } catch (IOException e) { System.out.println("IO异常.."); } } private void send_login(String content) { // 消息格式化(json格式) String message = messageFormat1(content); // 将消息封装成UDP数据包 byte[] buf = message.getBytes(); DatagramPacket packet = new DatagramPacket(buf, buf.length, ip, PORT); try { msg_send.send(packet); } catch (IOException e) { System.out.println("IO异常.."); } } private void send_go(String content) { String message = messageFormat2(content); // 将消息封装成UDP数据包 byte[] buf = message.getBytes(); DatagramPacket packet = new DatagramPacket(buf, buf.length, ip, PORT); try { msg_send.send(packet); } catch (IOException e) { System.out.println("IO异常.."); } } // 消息格式化 private String messageFormat0(String content) { StringBuffer buffer = new StringBuffer(); buffer.append("{\"isLogin\":\"").append(0).append("\","); buffer.append("\"groupId\":").append("\"").append(groupID).append( "\","); buffer.append("\"userName\":\"").append(clientName).append("\","); buffer.append("\"text\":\"").append(content).append("\"}"); return buffer.toString(); } private String messageFormat1(String content) { StringBuffer buffer = new StringBuffer(); buffer.append("{\"isLogin\":\"").append(1).append("\","); buffer.append("\"groupId\":").append("\"").append(groupID).append( "\","); buffer.append("\"userName\":\"").append(clientName).append("\","); buffer.append("\"text\":\"").append(content).append("\"}"); return buffer.toString(); } private String messageFormat2(String content) { StringBuffer buffer = new StringBuffer(); buffer.append("{\"isLogin\":\"").append(-1).append("\","); buffer.append("\"groupId\":").append("\"").append(groupID).append( "\","); buffer.append("\"userName\":\"").append(clientName).append("\","); buffer.append("\"text\":\"").append(content).append("\"}"); return buffer.toString(); } // 从服务器获取聊天室消息 public void pushBackMessage(MessageEntity me) { if(me.getIsLogin()==0) { ta.append(me.getUserName() + ":" + me.getText()); ta.append("\n"); }else if(me.getIsLogin()==1){ loginShow.setText(me.getUserName()+ "进入了聊天室!"); }else loginShow.setText(me.getUserName()+"离开了聊天室!"); } public void setShowClient(ArrayList<ChatClient> clients){ // for(ChatClient client:clients) { // showClient.append(client.clientName+"\n"); // } StringBuffer show=new StringBuffer(); show.append("当前聊天室人数:"+ChatServer.groups.get(groupID).size()+"\n"); for (ChatClient client:clients){ show.append(client.clientName+"\n"); } showClient.setText(show.toString()); } public void setShowClientNull(ArrayList<ChatClient> clients){ for(ChatClient client:clients) { showClient.setText(""); } } }
④消息处理服务端:
package com.ljh; import com.google.gson.Gson; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.SocketException; import java.util.ArrayList; import java.util.HashMap; public class ChatServer extends Thread{ // 端口号 private static final int PORT = 10000; // 套接字对象 private static DatagramSocket server = null; public static HashMap<String, ArrayList<ChatClient>> groups = new HashMap<String, ArrayList<ChatClient>>(); public ChatServer() { try { // 消息接受套接字对象的构造初始化 server = new DatagramSocket(PORT); } catch (SocketException e) { e.printStackTrace(); } } public static void logInGroup(String groupID, ChatClient client) throws SocketException { // 通过聊天室ID,获取该聊天室的所有在线用户 ArrayList<ChatClient> clients = groups.get(groupID); if (clients == null) { clients = new ArrayList<ChatClient>(); } // 将此次进入聊天室的用户登记 clients.add(client); // 更新聊天室信息 groups.put(groupID, clients); //显示在线用户 for (ChatClient chatClient:clients) { chatClient.setShowClientNull(clients); //由于textArea的局限性,只能全部删掉再重新加入 chatClient.setShowClient(clients); } } // 删除离开聊天室的用户 public static void leaveGroup(String groupID, ChatClient client) throws SocketException { // 通过聊天室id获取所有在线用户 ArrayList<ChatClient> clients = groups.get(groupID); if (clients == null) { clients = new ArrayList<ChatClient>(); } // 将离开聊天室的用户进行删除 clients.remove(client); // 更新聊天室信息 groups.put(groupID, clients); //显示在线用户 for (ChatClient chatClient:clients) { chatClient.setShowClientNull(clients); chatClient.setShowClient(clients); } } // 循环接收消息 @Override public void run() { while (true) { receiveMessage(); } } private void receiveMessage(){ byte[] buf = new byte[1024]; DatagramPacket packet = new DatagramPacket(buf, buf.length); while (true) { try { // 接受数据包 server.receive(packet); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 解析数据包,获取聊天信息 String content = new String(packet.getData(), 0, packet.getLength()); // 通过第三方包解析json数据 Gson gson = new Gson(); System.out.println(content); MessageEntity me = gson.fromJson(content, MessageEntity.class); // 解析消息内容,通过聊天室ID,获取该聊天室的所有在线用户 ArrayList<ChatClient> clients = groups.get(me.getGroupId()); // 将接收到的消息推送回该聊天室的各个用户 for (ChatClient client : clients){ client.pushBackMessage(me); } } } }
⑤创建聊天框
package com.ljh; import javax.swing.*; public class createFrame extends JFrame { JFrame createFrame1=new JFrame("创建聊天室"); JTextField createGroupId=new JTextField(); JButton okCreateButton=new JButton("ok"); public createFrame(){ createFrame1.setLayout(null); createFrame1.setSize(260,100); createGroupId.setBounds(20,20,100,20); okCreateButton.setBounds(170,20,50,20); createFrame1.add(createGroupId); createFrame1.add(okCreateButton); createFrame1.show(); } }
⑥封装消息类:
package com.ljh; public class MessageEntity { private String groupId; private String userName; private String text; private int isLogin=0; public String getGroupId() { return groupId; } public void setGroupId(String groupId) { this.groupId = groupId; } public int getIsLogin() { return isLogin; } public void setIsLogin(int isLogin) { this.isLogin = isLogin; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getText() { return text; } public void setText(String text) { this.text = text; } }
这篇关于java实现udp聊天室的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-26消息中间件源码剖析教程
- 2024-11-26JAVA语音识别项目资料的收集与应用
- 2024-11-26Java语音识别项目资料:入门级教程与实战指南
- 2024-11-26SpringAI:Java 开发的智能新利器
- 2024-11-26Java云原生资料:新手入门教程与实战指南
- 2024-11-26JAVA云原生资料入门教程
- 2024-11-26Mybatis官方生成器资料详解与应用教程
- 2024-11-26Mybatis一级缓存资料详解与实战教程
- 2024-11-26Mybatis一级缓存资料详解:新手快速入门
- 2024-11-26SpringBoot3+JDK17搭建后端资料详尽教程