使用UDP实现群聊聊天室

今天为大家带来了一个非常有意思的小程序——UDP实现的群聊聊天室。这个程序使用的UDP协议,并使用DatagramSocket的子类MulticastSocket实现组播,可以部署在一个局域网内的多台电脑上,并可以实现文字群聊。

按照以下几个小节讲解:
  
   1). 组播的概念:这个小节我们将讲解什么是:单播、广播、组播。
   2). MulticastSocket类的使用:这个小节我们将讲解MulticastSocket类的基本使用,并实现控制台的信息收发。
   3). 基于Swing和MulticastSocket实现的UDP群聊聊天室:**这个小节我们将制作一个界面,并结合MulticastSocket类实现一个完整的UDP群聊聊天室。
   4). 结束语:

一、组播的概念
  
   网络数据传播按照接收者的数量,可分为以下3种方式:
  
  1.1 单播:
  
   单播是指实现“点对点”的通信,发送者发送数据要发送给网络上的唯一的一台电脑,指定一个接收者。像TCP协议和UDP协议都能实现点对点通信。
  
  1.2 广播:
  
   发送者发送的数据可以被某个接收范围内所有的接收者接收。它类似于广播电台,向某个范围内的所有用户发送广播信号,接收人打开广播就可以听到,关闭广播设备就停止收听。由于广播会大大增加网络数据流量,所以通常情况下一些网络路由器会禁止广播数据,尤其是一些占用网络资源比较大的视频数据等。
  
  1.3 组播:
  
   组播是指发送的数据可以被指定的一组用户接收。组播的范围没有广播那么广,任何的一台电脑都可以随时加入某一个组接收组播数据。若要使用组播,则需要让一个数据报标有一组目标主机地址,当数据报发出后,整个组的所有主机都能收到该数据报。IP协议为组播提供了这批特殊的IP地址,这些IP地址的范围是224.0.0.0至239.255.255.255。在Java类库中,DatagramSocket有一个子类:MulticastSocket,它具有组播的功能,它可以与DatagramPackage结合使用,用于发送和接收组播包。
  
  二. MulticastSocket类的使用
  
   Java类库中MulticastSocket类可以实现组播功能,它是DatagramSocket的子类:
在这里插入图片描述
2.1 构造方法说明

通过API文档我们可以看到它有三个构造方法:

1. MulticastSocket() 创建一个多播套接字。(使用随机端口,如果只发送,可以使用这个构造方法)
2. MulticastSocket(int port) 创建一个多播套接字并将其绑定到一个特定的端口。(如果需要发送和接收,需要使用这个构造方法)
3. MulticastSocket(SocketAddress bindaddr) 创建一个多播套接字绑定到指定的套接字地址。

2.2 成员方法说明

以下是几个比较重要的成员方法:

1.public void joinGroup(InetAddress mcastaddr):将该MulticastSocket加入指定的多点广播地址。
2.public void leaveGroup(InetAddress mcastaddr让该MulticastSocket离开指定的多点广播地址。
3.public void setInterface(InetAddress inf):如果当前系统有多个网络接口,可以使用次方法指定一个网络接口。
4.public InetAddress getInterface():获取当前的网络接口。
5.public void setTimeToLive(int ttl):该参数设置数据报最多可以跨过多少个网络,当ttl为0时,指定数据报应停留在本地主机;当ttl的值为1时,指定数据报发送到本地局域网;当ttl的值为32时,意味着只能发送到本站点的网络上;当ttl为64时,意味着数据报应保留在本地区;当ttl的值为128时,意味着数据报应保留在本大洲;当ttl为255时,意味着数据报可发送到所有地方;默认情况下,该ttl的值为1

2.3 一个简单的示例

接下来我们写一个小例子来看一下MulticastSocket的使用方式。这个程序将包含两个线程:1. 接收线程,主要用于接收信息;2. 主线程,主要用于发送信息。将这个程序部署到局域网上的几台电脑上,全部启动,就可以实现多台电脑的组播了,而且每台主机都可以发出信息,其它主机则会收到这条信息。

package com.heima.se.chat;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.util.Date;
import java.util.Scanner;public class MulticastSocketDemo {public static void main(String[] args) throws IOException {//创建MuticastSocket对象,并监听端口55555MulticastSocket socket = new MulticastSocket(55555);//加入组:235.235.235.235socket.joinGroup(InetAddress.getByName("235.235.235.235"));//启动线程-此线程用于接收数据报new Thread(()->{byte[] bytes = new byte[1024];DatagramPacket packet = new DatagramPacket(bytes, bytes.length);while (true) {try {socket.receive(packet);System.out.println(new String(packet.getData(), 0, packet.getLength()));} catch (IOException e) {e.printStackTrace();}}}).start();//获取本机IPString localIp = InetAddress.getLocalHost().getHostAddress();//创建一个Scanner对象,用于接收控制台数据Scanner sc = new Scanner(System.in);while (true) {System.out.println("【请输入信息】");String msg = sc.next();// 获取当前时间格式化字符串,把IP、时间,以及要发送的文本连接在一起String time = String.format(" <====> %tF %<tT", new Date());msg = localIp + time + "\n" + msg + "\n\n";//发送数据报socket.send(new DatagramPacket(msg.getBytes(),msg.getBytes().length,InetAddress.getByName("235.235.235.235"),55555));}}
}

通过上面的程序,我们发现,MulticastSocket类的使用和DatagramSocket类基本相同,只是多了一步加入组:joinGroup(),所有加入这个组的主机都将会收到信息。

三. 基于Swing和MulticastSocket实现的UDP群聊聊天室
  
   接下来我们使用Swing为这个程序制作一个界面,让用户操作起来更加方便。
   这个程序我们制作了两个类:
   1). ChatFrame:这个类继承自JFrame,实现了界面的显示、布局等相关功能。
   2). SocketChat:这个类继承自ChatFrame,加入了MulticastSocket的连接、信息发送和接收。
  3.1 界面ChatFrame类

package com.heima.se.chat;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();//让发送文本框得到焦点}
}

这个类中定义了很多抽象方法,这些抽象方法由子类实现。

3.2 组播聊天SocketChat类

package com.heima.se.chat;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;//群组Socketpublic SocketChat() throws IOException {socket = new MulticastSocket(54321);//创建群组Socket,绑定54321端口//加入虚拟IP:235.235.235.235指定的群组中。虚拟IP范围是:224.0.0.1239.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 {// 创建数据包的字节数组,大小为1KBbyte[] 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);}
}

这个类使用MulticastSocket,使用端口:54321,组播地址:235.235.235.235。当用户在界面按下send按钮时,会触发sendText()方法发送数据;receive()方法用于使用线程接收数据,它是在父类的构造方法中被触发启动,启动后,使用无限循环进行信息的接收。
 
Java基础入门:

java零基础自学首Java入门教程(含Java项目和Java真题)

Javaweb核心基础

JavaWeb基础教程,Java web从入门到企业实战完整版

Spring Cloud最全微服务架构

史上最全面的springcloud微服务技术栈

SSM框架教程:

SSM框架教程_Spring+SpringMVC+Maven高级+Spring

SpringBoot2全套视频教程:

SpringBoot2全套视频教程,springboot零基础到项目实战

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【WhatsApp营销】如何为企业构建WhatsApp聊天机器人

关键词&#xff1a;WhatsApp营销&#xff0c;聊天机器人 WhatsApp是全球最受欢迎的消息应用之一。它拥有超过20亿活跃用户&#xff0c;而且目前这个数字还在稳步增长。对于个人来说&#xff0c;WhatsApp是朋友、家人间线上沟通的重要渠道&#xff1b;对于企业而言&#xff0c;…

虚拟人纷纷「出道」,社交泛娱乐场景如何迎接新顶流?

⬆️“政企数智办公行业研究报告及融云新品发布会”明天直播&#xff01; 本月 12 日&#xff0c;花房集团即将于香港上市。关注【融云全球互联网通信云】回复【融云】抽取高颜值大容量高端可乐保温杯哦~ 中国政企数智办公平台 在带货直播平台的赫赫之名下&#xff0c;娱乐直播…

Unity 3D 使 用 MQTT 实 现 数 据 通 信

最近学习需要在Unity中用到MQTT通信&#xff0c;CSDN下载了一些资料都有报错&#xff08;主要是也不太看得懂代码不会改&#xff09;&#xff0c;跟B站up复现了一个简单的demo算是加深了一些学习&#xff0c;有需要的初学者可以自取。 demo实现步骤大致如下 1.HslCommunicati…

太猛了!ChatGPT 到 Moss 足以窥见人工智能的未来

最近大家圈内的话题&#xff0c;是不是除了ChatGPT还是ChatGPT&#xff0c;感觉不聊点ChatGPT都跟不上大家的脚步了。各大社交平台上充斥着各式各样与ChatGPT相关的话题&#xff0c;估计大家都在主动或被动的接收ChatGPT的相关资讯。 今天&#xff0c;我们的重点不在ChatGPT&am…

【方案分享】茶叶品牌小罐茶2020品牌营销推广方案.pdf(附下载链接)

大家好&#xff0c;我是文文&#xff0c;今天给大家分享一份品牌营销干货资料《茶叶品牌小罐茶2020品牌营销推广方案.pdf》,对小罐茶以及品牌营销感兴趣的伙伴别错过啦&#xff01; 另外&#xff0c;我们也搭建了行业交流社群&#xff0c;涵盖营销、电商、互联网、数字化、汽车…

酒水销售网站

开发工具(eclipse/idea/vscode等)&#xff1a; 数据库(sqlite/mysql/sqlserver等)&#xff1a; 功能模块(请用文字描述&#xff0c;至少200字)&#xff1a; 网站前台&#xff1a;网站介绍、帮助信息、酒水资讯、酒水类型、酒水信息、购物分享 管理员&#xff1a; 1、管理网站介…

什么是品牌营销?学会正确推广您的业务

什么是品牌营销&#xff1f; 品牌营销涉及长期战略规划&#xff0c;以推广整个品牌&#xff0c;而不是营销单个产品或服务。它分享了一个引人入胜的故事&#xff0c;以在潜在客户中产生品牌知名度并建立声誉。 面向消费者的品牌使用品牌智能软件来了解人们对其品牌的看法&#…

酒楼拓客营销流程,酒楼宣传推广方案

随著网络时代的发展&#xff0c;许多行业受到了大大的冲击&#xff0c;其中也涵盖酒楼&#xff0c;在目前的情况下&#xff0c;对于酒楼来说&#xff0c;无论是互联网还是线下&#xff0c;引流都是最重要的。那么酒楼如何做好营销推广工作&#xff0c;从而提升业绩&#xff1f;…

小众渠道酒水销售怎么找客户?

一说起酒水大家好像想当然地认为很好销售&#xff0c;但是普通大众只知道广告打得最响的那几个品牌&#xff0c;对于其他酒水并不了解&#xff0c;甚至闻所未闻&#xff0c;所以并不愿意花钱去购买这些中高端的酒水。于是很多企业开始另辟蹊径&#xff0c;不走平民路线&#xf…

如何用ChatGPT举办活动,人类与AI的一次深度对谈

刚刚&#xff0c;Mixlab今年首次线下联合举办的活动开启了&#xff0c;活动不仅分享了AIGC对体验设计的新要求、内容产业的发展研判、用于模拟仿真的生成式智能体&#xff0c;还演示了AI如何深度整合到一场活动之中。 1/ 数字人出场介绍Mixlab 是如何实现的呢&#xff1f;无限…

为什么在马云成功前就有那么多影像留下来?

马云创业的各个阶段&#xff0c;都有意无意得到媒体的推波助澜&#xff0c;不光是影像&#xff0c;还留下了很多相关的文字报道。站在当时的角度&#xff0c;马云或许并不总是以一种成功人士的身份出现&#xff0c;但即便如此&#xff0c;他做事情也足够新潮、足够前卫、或者足…

记录:ffmpeg视频切片

简介 关于视频切片及播放&#xff0c;在这里简单做一个记录。 环境及安装包 服务器&#xff1a;CentOS 版本&#xff1a;CentOS Linux release 7.5.1804 (Core) FFMpeg资源包&#xff1a;ffmpeg-3.1.tar.gz yasm-1.3.0.tar.gz 安装FFmpeg 1.下…

ffmpeg视频切片方案

1.视频播放存在的问题 前提介绍:首先是需要是需要把摄像机的视频接到我们的平台上,目前存在两种方式,一种是需要客户端去实现,一种是在服务器端实现,都是基于ffmpeg去做的 客户端实现,由于客户端有无数个,每一个客户端都去看同一个摄像机视频的时候,摄像机的压力是很大的 1…

python篇---视频切分成图片

视频切分成图片 使用python将视频分割成图片 python版本&#xff1a; 3.7.11 使用到的库&#xff1a;opencv (安装命令&#xff1a;pip install opencv-python) import os import cv2# 定义保存图片函数 # image:要保存的图片 # pic_address&#xff1a;图片保存地址 # num: …

moviepy快速切分视频并保存片段

文章目录 1、直接使用ffmepg2、使用moviepy本身 moviepy安装最新版本&#xff1a; pip install moviepy --pre --upgrade版本是v2.0.0.dev2。 有两种方法一种快速的&#xff1a; 1、直接使用ffmepg from moviepy.video.io.ffmpeg_tools import ffmpeg_extract_subclip ffmpeg…

ffmpeg视频截取切片

通过segment_format指定切片文件的格式 ffmpeg -re -i input.mp4 -c copy -f segment -segment_format mp4 test_outpout-%d.mp4 查看分片文件的开始时间跟结束时间 开始时间&#xff1a; ffprobe -v quiet -show_packets -select_streams v test_outpout-0.mp4 2> x |g…

FFmpeg视频切片

为了解决项目中视频大的问题&#xff0c;我的想法是把视频切分成一小段一小段的短视频&#xff0c;然后按序播放。 m3u8是一项新型播放格式&#xff0c;这种播放格式支持目前市面的windows、androis、ios设备主流的浏览器&#xff0c;同样的视频文件既可以在Flash环境播放&…

关于GPT、AI绘画、AI提词器等AI技术的探讨

目前的AI潮流非常火热&#xff0c;CHATGPT可谓是目前大模型人工智能的代表&#xff0c;刚开始听说chatGPT可以写代码&#xff0c;写作&#xff0c;写方案&#xff0c;无所不能。还有AI绘画也很&#xff2e;&#xff22;作为一个程序员&#xff0c;为了体验这些&#xff21;&…

【回答问题】ChatGPT上线了!给我推荐20个比较流行的图像全景分割模型

给我推荐20个比较流行的图像全景分割模型 好的,这是 20 个比较流行的图像全景分割模型:DeepLabv3+ PSPNet FCN U-Net Mask R-CNN UNet++ SegNet ENet ICNet ENet GCN DANet BiSeNet DenseASPP DenseASPPv2 DenseASPPv3 DenseASPPv4 DenseASPPv5 DenseASPPv6 DenseASPPv7 希望…

用户画像洞察分类模型 - 前端页面展示

文章目录 一、前端与数据智能二、 体验优化需求场景跳失预测交互偏好智能 UI 三、 关键技术鲸幂 UICook&#xff08;智能UI&#xff09;DataCookPipCookPipeline 四、 体验优化实践数据智能实践的一般流程数据采集数据分析 -如何对数据进行分析处理并得出结论数据应用 - 分析结…