Java利用UDP实现简单群聊

news2025/1/21 1:49:58

一、创建新项目
首先新建一个新的项目,并按如下操作

二、实现代码
界面ChatFrame类
package 群聊;
 
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.net.InetAddress;
 
public abstract class ChatFrame extends JFrame {
    private JTextArea receiveArea = new JTextArea();//接收文本框,用来显示服务器发送过来的文本
    private JTextArea sendArea = new JTextArea();//发送文本框,用来显示当前用户要发送的文本
 
    private JButton sendBtn = new JButton("SEND");//发送按键
 
    public ChatFrame() {
        this.initFrame();//初始化窗口
        this.initComponent();//初始化组件
        this.initListener();//初始化监听器
        this.receive();//开启监听服务器线程,把接收到的文本显示在receiveArea中
    }
 
    // 初始化监听器
    private void initListener() {
        // 给发送按键添加监听器,当被点击时调用send()方法
        sendBtn.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                send();
            }
        });
 
        // 给发送文本框添加键盘监听器,当按下Ctrl+ENTER时调用send()方法
        sendArea.addKeyListener(new KeyAdapter() {
            public void keyPressed(KeyEvent e) {
                if(e.isControlDown()) {
                    if(e.getKeyCode() == KeyEvent.VK_ENTER) {
                        send();
                    }
                }
            }
        });
    }
 
    // 子类需要重写本方法
    // 在本方法中使用socket实现消息发送
    public abstract void sendText(String text);
 
    // 子类需要重写本方法
    // 在本方法中启动监听服务器线程,调用本类receiveText(String)把接收到的文本显示出来
    public abstract void receive();
 
    // 本方法用来发送文本
    public void send() {
        // 如果发送文本框中没有文本,弹出警告对话框
        if(sendArea.getText().equals("")) {
            javax.swing.JOptionPane.showMessageDialog(this, "空文本不能发送!");
            sendArea.requestFocus();// 把光标归还给发送文本框
            return;
        }
 
        // 调用子类的方法完成文本发送
        sendText(sendArea.getText());
        // 把发送文本框内容清空
        sendArea.setText(null);
    }
 
    // 本方法完成接收服务器消息的后续工作-在文本框中显示服务器消息,子类的receive()方法在接收服务器消息后可以调用本方法
    public void receiveText(String text) {
        receiveArea.append(text);//把接收到的消息添加到文本框中
        // 设置光标位置到最后,如果不设置滚动条不动
        receiveArea.setCaretPosition(receiveArea.getText().length());
    }
 
    // 初始化组件
    private void initComponent() {
        // 使用接收文本框创建滚动窗口(把文本框添加到了滚动窗口中),总是显示纵向滚动条,永不显示横向滚动条
        JScrollPane sp1 = new JScrollPane(receiveArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        // 设置滚动窗口大小、位置、无边框;并把滚动窗口添加到主窗口中
        sp1.setSize(606, 350);
        sp1.setLocation(14, 20);
        sp1.setBorder(null);
        this.add(sp1);
 
        // 设置接收文本框背景色、不可编辑、自动换行
        receiveArea.setBackground(new Color(238, 238, 238));
        receiveArea.setEditable(false);
        receiveArea.setLineWrap(true);
 
        // 创建发送文本框的滚动窗口,设置自动换行、大小、位置,然后添加到主窗口中
        JScrollPane sp2 = new JScrollPane(sendArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        sendArea.setLineWrap(true);
        sp2.setSize(606, 145);
        sp2.setLocation(14, 400);
        this.add(sp2);
 
        // 设置发送按键的大小、位置,并添加到主窗口中
        sendBtn.setSize(68, 21);
        sendBtn.setLocation(553, 560);
        this.add(sendBtn);
 
        // 设置主窗口的标题为当前IP地址
        try {
            this.setTitle(InetAddress.getLocalHost().getHostAddress());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
 
    // 初始化主窗口
    private void initFrame() {
        // 设置主窗口的大小、布局管理器为空、背景色、位置、大小不可改变
        this.setSize(640, 620);
        this.setLayout(null);
        this.setBackground(new Color(246, 246, 247));
        this.setLocation(350, 50);
        this.setResizable(false);
 
        // 设置主窗口的“X”按钮点击后结束程序
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
 
    // 显示主窗口方法
    public void setVisible(boolean b) {
        super.setVisible(b);//调用父类的显示方法
        sendArea.requestFocus();//让发送文本框得到焦点
    }
}

组播聊天SocketChat类
package 群聊;
 
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.util.Date;
 
/**
 * 本类继承了ChatFrame,ChatFrame实现了GUI显示
 * 本类负责使用MulticastSocket完成群聊的发送消息与接收消息
 */
public class SocketChat extends ChatFrame {
    private MulticastSocket socket;//群组Socket
 
    public SocketChat() throws IOException {
        socket = new MulticastSocket(54321);//创建群组Socket,绑定54321端口
        //加入虚拟IP:235.235.235.235指定的群组中。虚拟IP范围是:224.0.0.1 和 239.255.255.255
        //加入群组后,就可以接收群组的消息,也可以向群组发送消息了
        socket.joinGroup(InetAddress.getByName("235.235.235.235"));
    }
 
    // 发送消息方法
    public void sendText(String text) {
        try {
            // 获取IP地址
            String ip = InetAddress.getLocalHost().getHostAddress();
            // 获取当前时间格式化字符串
            String time = String.format(" <====> %tF %<tT", new Date());
            // 把IP、时间,以及要发送的文本连接在一起
            text = ip + time + "\n" + text + "\n\n";
            // 把文本转换成字节数组
            byte[] buff = text.getBytes();
            // 使用socket向群组发送,socket的send()方法需要两个参数:DatagramPacket、端口号
            // DatagramPacket表示数据包,创建它需要三个参数:数据包的内容、数据包的字节数、要发送的IP地址
            socket.send(new DatagramPacket(buff, buff.length, InetAddress.getByName("235.235.235.235"), 54321));
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
 
    // 本方法用来接收群组发送过来的消息
    public void receive() {
        // 创建监听群组消息的线程,并启动它
        new Thread() {
            public void run() {
                // 循环监听
                while(true) {
                    try {
                        // 创建数据包的字节数组,大小为1KB
                        byte[] buff = new byte[1024];
                        // 创建数据包
                        DatagramPacket dp = new DatagramPacket(buff, buff.length);
                        // 接收群组发送过来的消息到数据包中
                        // 本方法会阻塞当前线程,直到接收到消息为止
                        socket.receive(dp);
                        // 把接收到的消息转换成字符串
                        String text = new String(dp.getData(), 0, dp.getLength());
                        // 调用父类的方法完成显示
                        receiveText(text);
                    } catch(Exception e) {}
                }
            }
        }.start();
    }
 
    public static void main(String[] args) throws IOException {
        SocketChat sc = new SocketChat();
        sc.setVisible(true);
    }
}

三、运行结果


运行的第一个窗口成员1

第二个窗口为成员2

第三个窗口为成员3

由此可见、新建窗口=添加成员

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1290392.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于OpenCV+CNN+IOT+微信小程序智能果实采摘指导系统——深度学习算法应用(含pytho、JS工程源码)+数据集+模型(一)

目录 前言总体设计系统整体结构图系统流程图 运行环境Python环境TensorFlow 环境Jupyter Notebook环境Pycharm 环境 相关其它博客工程源代码下载其它资料下载 前言 本项目基于Keras框架&#xff0c;引入CNN进行模型训练&#xff0c;采用Dropout梯度下降算法&#xff0c;按比例…

MAC 系统在vs code中,如何实现自动换行

目录 问题描述&#xff1a; 问题解决&#xff1a; 问题描述&#xff1a; 在vscode中&#xff0c;有些时候&#xff0c;一行内容过多&#xff0c;如果不能自动换行&#xff0c;就需要拖动页面&#xff0c;才能看到完整的内容。如下图两行所示&#xff1a; 问题解决&#xff1a…

华为数通---使用基本ACL限制Telnet登录权限案例

组网需求 如下图所示&#xff0c;PC与设备之间路由可达&#xff0c;用户希望简单方便的配置和管理远程设备&#xff0c;可以在服务器端配置Telnet用户使用AAA验证登录&#xff0c;并配置安全策略&#xff0c;保证只有符合安全策略的用户才能登录设备。 配置通过Telnet登录设备…

在Spring Cloud中使用组件Ribbon和Feign,并分别创建子模块注册到Eureka中去

ok&#xff0c;在上篇文章中我们讲了在Spring cloud中使用Zuul网关&#xff0c;这篇文章我们将Spring Cloud的五大核心组件的Ribbon和Feign分别创建一个微服务模块。 题外话&#xff0c;本篇博客就是配置子模块&#xff0c;或者说是微服务&#xff0c;然后将微服务正式启动之前…

2024年江苏省职业院校技能大赛信息安全管理与评估 第三阶段教师组(样卷)

2024年江苏省职业院校技能大赛信息安全管理与评估 第三阶段教师组&#xff08;样卷&#xff09; 竞赛项目赛题 本文件为信息安全管理与评估项目竞赛-第三阶段教师组样题&#xff0c; 内容包括&#xff1a;网络安全渗透、理论技能与职业素养。 本次比赛时间为180分钟。 介绍 Ge…

Unity中Batching优化的GPU实例化(1)

文章目录 前言一、GPU实例化的规则1、必须满足 Mesh 网格一样2、只有OpenGL es 3.0及以上才支持&#xff08;3.0及以上有部分硬件可能也不支持&#xff09; 二、GPU实例化的应用场景1、公开几个成员属性&#xff0c;用于存放可以调整的数据2、用Random.insideUnitCircle随机生成…

Linux(ubuntu)利用ffmpeg+qt设计rtsp_rtmp流媒体播放器(完全从0开始搭建环境进行开发)

一、前言 从0开始搭建Linux下Qt、ffmpeg开发环境。 从安装虚拟机开始、安装Linux(Ubuntu)系统、安装Qt开发环境、编译ffmpeg源码、配置ffmpeg环境、编写ffmpeg项目代码、完成项目开发。 完全从0开始搭建环境进行开发 完全从0开始搭建环境进行开发 完全从0开始搭建环境进行开…

决策树 (人工智能期末复习)

几个重要概念 信息熵&#xff1a;随机事件未按照某个属性的不同取值划分时的熵减去按照某个属性的不同取值划分时的平均 熵。即前后两次熵的差值。 表示事物的混乱程度&#xff0c;熵越大表示混乱程度越大&#xff0c;越小表示混乱程度越小。 对于随机事件&#xff0c;如果它的…

【Hadoop_01】Hadoop介绍与安装

1、Hadoop、HDFS、YARN介绍&#xff08;1&#xff09;Hadoop简介与优势&#xff08;2&#xff09;Hadoop组成&#xff08;3&#xff09;HDFS概述&#xff08;4&#xff09;YARN概述&#xff08;5&#xff09;MapReduce概述 2、安装&#xff08;1&#xff09;Centos7.5软硬件安装…

数据仓库与数据挖掘复习资料

一、题型与考点[第一种] 1、解释基本概念(中英互译解释简单的含义)&#xff1b; 2、简答题(每个10分有两个一定要记住)&#xff1a; ① 考时间序列Time series(第六章)的基本概念含义解释作用&#xff08;序列模式挖掘的作用&#xff09;&#xff1b; ② 考聚类(第五章)重点考…

用23种设计模式打造一个cocos creator的游戏框架----(四)装饰器模式

1、模式标准 模式名称&#xff1a;装饰器模式 模式分类&#xff1a;结构型 模式意图&#xff1a;动态地给一个对象添加一些额外的职责。就增加功能来说&#xff0c;装饰器模式比生成子类更为灵活。 结构图&#xff1a; 适用于&#xff1a; 当需要给一个对象在运行时添加更…

Linux系统调试课:网络性能工具总结

文章目录 一、网络性能指标二、netstat三、route四、iptables沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇章一起了解下网络性能工具。 一、网络性能指标 从网络性能指标出发,你更容易把性能工具同系统工作原理关联起来,对性能问题有宏观的认识和把握。这样,…

网络层之IP数据报格式、数据报分片、IPv4、子网划分和子网掩码

学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持&#xff0c;想组团高效学习… 想写博客但无从下手&#xff0c;急需…

轻快小miniconda3在linux下的安装配置-centos9stream-Miniconda3 Linux 64-bit

miniconda与anaconda的区别&#xff1a; Miniconda 和 Anaconda 是用于管理环境和安装软件包的 Python 发行版。它们之间的主要区别在于以下几点&#xff1a; 1. 安装内容和大小&#xff1a; Anaconda&#xff1a; Anaconda 是一个完整的 Python 数据科学平台&#xff0c;包含…

Kafka使用指南

Kafka简介架构设计Kafka的架构设计关键概念Kafka的架构设计关键机制 Partition介绍Partition工作机制 应用场景ACK机制介绍ACK机制原理ACK机制对性能的影响ACK控制粒度Kafka分区数对集群性能影响调整分区优化集群性能拓展Kafka数据全局有序 Kafka简介 Kafka是由Apache软件基金…

零基础小白怎么准备蓝桥杯-蓝桥杯竞赛经验分享

零基础小白怎么准备蓝桥杯-蓝桥杯竞赛经验分享 前言竞赛简介竞赛目的如何备战1.基础学习2.实战训练&#xff08;非常重要&#xff09; 资料分享 前言 博主在蓝桥杯中获得过十四届Java B 组的省一国二&#xff0c;本文为大家介绍一下蓝桥杯并分享一下自己的参赛经验。 竞赛简介…

2024年江苏省职业院校技能大赛信息安全管理与评估 第三阶段学生组(样卷)

2024年江苏省职业院校技能大赛信息安全管理与评估 第三阶段学生组&#xff08;样卷&#xff09; 竞赛项目赛题 本文件为信息安全管理与评估项目竞赛-第三阶段样题&#xff0c;内容包括&#xff1a;网络安全渗透、理论技能与职业素养。 本次比赛时间为180分钟。 介绍 GeekSe…

分享“技艺与传承”的魅力!春城晚报(开屏新闻)生活节第七期媒体开放日活动举行

近日&#xff0c;由云南报业传媒&#xff08;集团&#xff09;有限责任公司、云南春晚传媒有限公司指导&#xff1b;金格金俊广场、云南精品文化传媒有限公司联合主办的第七期媒体开放日活动在金格金俊广场B1共享空间举办。本次活动以「技艺与传承」为主题&#xff0c;特邀青年…

TP5上传图片压缩尺寸

图片上传&#xff0c;最简单的就是&#xff0c; 方法一&#xff1a; 修改上传限制&#xff0c;不让上传大于多少多少的图片 改一下size即可&#xff0c;默认单位是B换算成M还需要除以两次1024 方法二&#xff1a; 对上传的图片进行缩放&#xff0c;此办法网上找了不少的代码…

ELK 日志解决方案

ELK 是目前最流行的集中式日志解决方案&#xff0c;提供了对日志收集、存储、展示等一站式的解决方案。 ELK 分别指 Elasticsearch、Logstash、Kibana。 Elasticsearch&#xff1a;分布式数据搜索引擎&#xff0c;基于 Apache Lucene 实现&#xff0c;可集群&#xff0c;提供…