Java利用UDP实现简单群聊
一、创建新项目
首先新建一个新的项目,并按如下操作

二、实现代码
界面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
由此可见、新建窗口=添加成员
相关文章:
Java利用UDP实现简单群聊
一、创建新项目 首先新建一个新的项目,并按如下操作 二、实现代码 界面ChatFrame类 package 群聊; import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.net.InetAddress; public abstract class ChatFrame extends JFrame { p…...
fastapi.templating与HTMLResponse
要声明一个模板对象,应将存储html模板的文件夹作为参数提供。在当前工作目录中,我们将创建一个 “templates “目录。 templates Jinja2Templates(directory“templates”) 我们现在要把这个页面的HTML代码渲染成HTMLResponse。让我们修改一下hello()函…...
当初为什么选择计算机这类的行业?
CSDN给了这么一个话题: 还记得当初自己为什么选择计算机? 当初你问我为什么选择计算机,我笑着回答:“因为我梦想成为神奇的码农!我想像编织魔法一样编写程序,创造出炫酷的虚拟世界!”谁知道&…...
tif文件转png、Excel
l利用gdal读取tif中的地理信息和波段数组,然后保存想要的格式即可。 from osgeo import gdal from PIL import Image import numpy as np import cv2 as cv from matplotlib import pyplot as plt# 读取.tif文件 def read_tif(file_path):dataset gdal.Open(file_…...
【PyTorch】训练过程可视化
文章目录 1. 训练过程中的可视化1.1. alive_progress1.2. rich.progress 2. 训练结束后的可视化2.1. tensorboardX2.1.1. 安装2.1.2. 使用 1. 训练过程中的可视化 主要是监控训练的进度。 1.1. alive_progress 安装 pip install alive_progress使用 from alive_progress i…...
深入理解Go语言GC机制
1、Go 1.3之前的标记-清除(mark and sweep)算法 Go 1.3之前的时候主要用的是普通的标记-清除算法,此算法主要由两个主要的步骤: 标记(Mark phase)清除(Sweep phase) 1)…...
qt-C++笔记之组件-分组框QGroupBox
qt-C笔记之组件-分组框QGroupBox code review! 文章目录 qt-C笔记之组件-分组框QGroupBox1.《Qt 6 C开发指南》p752.《Qt 官方文档》3.《Qt 5.12实战》——5.9 分组框控件 1.《Qt 6 C开发指南》p75 2.《Qt 官方文档》 中间段落翻译: 我把示例补充完整: …...
qt 定时器用法
在qt开发中,定时器是我们经常用到的。我们接下来说一下定时器的三种用法,需要注意的是定时器事件是在主线程中触发的,因此在处理耗时操作时应特别小心,以避免阻塞应用程序的事件循环。 1. 三种定时器使用 1.1 QObject的定时器 …...
用23种设计模式打造一个cocos creator的游戏框架----(九)访问者模式
1、模式标准 模式名称:访问者模式 模式分类:行为型 模式意图:将数据操作与数据结构分离,使得在不修改数据结构的前提下,可以添加或改变对数据的操作。 结构图: 适用于: 当你需要对一个复杂对…...
根文件系统初步测试
一. 简介 上一篇文章学习了向所编译生成的根文件系统中加入 lib库文件。文章地址如下: 根文件系统lib库添加与初步测试-CSDN博客 本文继上一篇文章的学习,本文对之前制作的根文件系统进行一次初步测试。 二. 根文件系统初步测试 为了方便测试&#…...
【精选】设计模式——策略设计模式-两种举例说明,具体代码实现
Java策略设计模式 简介 策略设计模式是一种行为型设计模式,它允许在运行时选择算法的行为。 在软件开发中,我们常常需要根据不同情况采取不同的行为。通常的做法是使用大量的条件语句来实现这种灵活性,但这会导致代码变得复杂、难以维护和扩…...
外包干了3个月,技术倒退2年。。。
先说情况,大专毕业,18年通过校招进入湖南某软件公司,干了接近6年的功能测试,今年年初,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…...
微信小程序:chooseimage从本地相册选择图片或使用相机拍照
文档 https://uniapp.dcloud.net.cn/api/media/image.html#chooseimage https://developers.weixin.qq.com/miniprogram/dev/api/media/image/wx.chooseImage.html 代码示例 const res await uni.chooseImage({count: 1, //默认9sizeType: [original, compressed], //可以…...
「Swift」取消UITableView起始位置在状态栏下方开始
前言:在写页面UI时发现,当隐藏了NavigationBar时,即使UITableView是从(0,0)进行布局,也会一直在手机状态栏下方进行展示布局,而我的想法是希望UITableView可以从状态栏处就进行展示布局 当前页面展示: 问题…...
android高版本适配使用Tools.java
随着android版本的提升,原生Tools不公开并且不能被正常使用,为了延续项目的功能,修改如下: /** Copyright (C) 2006 The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License&quo…...
面试官:说说webpack中常见的Loader?解决了什么问题?
面试官:说说webpack中常见的Loader?解决了什么问题? 一、是什么 loader 用于对模块的"源代码"进行转换,在 import 或"加载"模块时预处理文件 webpack做的事情,仅仅是分析出各种模块的依赖关系&a…...
【蓝桥杯省赛真题50】Scratch智能计价器 蓝桥杯scratch图形化编程 中小学生蓝桥杯省赛真题讲解
目录 scratch智能计价器 一、题目要求 编程实现 二、案例分析 1、角色分析...
折半查找(数据结构实训)
题目: 标准输入输出 题目描述: 实现折半查找。要求查找给定的值在数据表中相应的存储位置。本题目假定输入元素均按非降序输入。 输入: 输入包含若干个测试用例,第一行为测试用例个数k。每个测试用例占3行,其中第一行为…...
AR助推制造业智能转型:实时远程协作与可视化引领生产创新
制造商面临着多方面的变革,技术的兴起催生了工业物联网(IIoT),改变了现代工厂的外貌、系统和流程。同时,全球竞争压力和不断变化的员工队伍要求采用新的员工培训方法,并重新审视工人在工厂中的角色。尽管如…...
【用unity实现100个游戏之18】从零开始制作一个类CSGO/CS2、CF第一人称FPS射击游戏——基础篇3(附项目源码)
文章目录 本节最终效果前言素材人物移动音效枪口火焰和开火音效枪口灯光弹孔和火花添加武器随镜头手臂摇摆效果源码完结 本节最终效果 前言 本节主要实现添加音效,和一些特效、武器摆动调整。 素材 素材,为了方便我直接用了unity免费的音效输出&#…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...
【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器
一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...
深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...
家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...
大学生职业发展与就业创业指导教学评价
这里是引用 作为软工2203/2204班的学生,我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要,而您认真负责的教学态度,让课程的每一部分都充满了实用价值。 尤其让我…...
