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;
    }
}
  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值