网络编程 | UDP组播通信
1、什么是组播
在上一篇博客中,对UDP的广播通信进行了由浅入深的总结梳理,本文继续对UDP的知识体系进行探讨,旨在将UDP的组播通信由浅入深的讲解清楚。
组播是介于单播与广播之间,在一个局域网内,将某些主机添加到组中,并设置一个组地址。将数据发送到组播地址时,加入到该组的所有主机都能接收到数据。
组播、单播和广播都是报文传输的一种方式。
单播是主机间一对一的通信模式,设备只会将数据发送到唯一指定的接收者。
广播是主机间一对所有的通信模式,设备会将数据发送到网络中的所有可能的接收者。设备简单地将它收到的任何广播报文都复制并转发到除该报文到达的接口外的每个接口。广播处理流程简单,不用选择路径。
组播是主机间一对多的通信模式, 组播是一种允许一个或多个组播源发送同一报文到多个接收者的技术。类似于生活中较为常见的群聊功能,在群内的所有群员,都可以在群内发送消息给群友,也可以接收到来自任意群友的消息。
为了帮助读者更进一步的理解UDP的单播、组播和广播功能,绘制了如下所示的总结图。

2、IP地址分类
因为组播通信需要设置IP地址,且必须是D类IP地址,但是考虑到每位博客读者的基础不同,知识贮备有较大差距,所以在这一小部分,简单讲解一下IP地址的分类及用途,在后面程序设计中需要用到这个E类IP地址。
IP地址 = 网络号 + 主机号
网络号:指的是不同的网络
主机号:指的是同一个网段下用来识别不同的主机。那也就是说,主机号所占的位数越多,在该网段下的主机数越多。
A类地址:保留给政府机构使用
A类IP地址就由1字节的网络地址和3字节主机地址组成,网络地址的最高位必须是“0”
A类地址范围 1.0.0.1 - 126.255.255.254
B类地址:分配给中等规模的公司
B类IP地址就由2字节的网络地址和2字节主机地址组成,网络地址的最高位必须是“10”。
B类地址范围 128.0.0.1 - 191.255.255.254
C类地址:分配给任何需要的人
C类IP地址就由3字节的网络地址和1字节主机地址组成,网络地址的最高位必须是“110”。
C类地址范围 192.0.0.1 - 223.255.255.254
D类地址:用于组播
组播地址不同于单播地址,它并不属于特定某个主机,而是属于一组主机。一个组播地址表示一个群组,需要接收组播报文的接收者都加入这个群组。
D类地址范围 224.0.0.1 - 239.255.255.254
E类地址:用于实验
E类地址范围 240.0.0.1 - 255.255.255.254
特殊地址:每一个字节都为0的地址(“0.0.0.0”)对应于当前主机; INADDR_ANY —>代表当前主机所有的地址
127.0.0.1 回环地址 —> 在当前主机内部自动形成闭环的网络 —> 主要用于主机内部不同的应用程序间通信
如果已经确定当前客户端 和 服务器 都是在同一台主机上运行,那么可以使用本地回环地址
3、组播的特点及应用
(1)、特点
- 效率高:组播传输的数据包只需要经过一次发送操作,就可以同时传输到多个接收者,可以有效地降低网络传输的负载。
- 可扩展性:组播支持动态加入和退出组播组,能够自适应地处理组播成员的加入和离开。
- IP组播地址:在IPv4中,组播使用D类地址(224.0.0.0至239.255.255.255),而在IPv6中,组播地址以ff00::/8开头。这些特殊地址用于标识不同的组播组,使路由器能够识别并正确转发组播报文。
- 路由协议的支持:为有效管理组播流量,互联网工程任务组(IETF)定义了几种专门的组播路由协议,如PIM(Protocol Independent Multicast)、DVMRP(Distance Vector Multicast Routing Protocol)等,它们帮助确定最有效的路径来分发组播数据。
- 不可靠性:与普通的UDP一样,组播只提供不可靠的数据传输服务。如果某个接收者没有接收到数据包,发送者不会得到任何提示或反馈信息。
(2)、应用
- 多媒体流媒体:在局域网或广域网上传输音视频流,快速向多个接收者发送相同的视频和音频数据。
- 分布式应用的数据分发:实现高效的数据分发,例如在大型集群环境下广播服务的状态信息。
- 网络游戏:用于多人联机游戏,使多个玩家能够同时收到相同的游戏状态和动作。
- 网络广播:向多个设备广播事件和消息,例如路由器向所有连接的设备发送网络配置信息。
- 实时数据更新:用于实时的数据更新,例如在金融行业订阅财经数据的实时更新。
4、组播的通信流程
组播通信的发送端程序与普通UDP发送端创建流程几乎一致,区别在于,其目标IP地址需要换成D类IP地址。
组播通信的接收端则是需要在普通UDP接收端程序的基础上,增加一步“加群”的操作,即将当前的IP地址设置到组播地址中。

5、组播通信的程序
(1)、组播发送端步骤
①、创建UDP套接字
int socketfd = socket(AF_INET,SOCK_DGRAM,0);
②、发送数据,往组播地址(224.0.0.10 )里面发送数据
struct sockaddr_in sendAddr;//IPV4地址结构体变量
sendAddr.sin_family = AF_INET;
sendAddr.sin_port = htons(GROUPPORT);
sendAddr.sin_addr.s_addr = inet_addr(GROUPADDR);//一定是组播地址
sendto(socketfd, buf, strlen(buf), 0, (struct sockaddr *)&sendAddr, sizeof(sendAddr));
③、关闭套接字
close(socketfd);
(2)、组播接收端步骤
①、创建UDP套接字
int socketfd = socket(AF_INET, SOCK_DGRAM, 0);
②、设置组播ip(初始化 组播结构体)
函数原型:#include <arpa/inet.h>int inet_pton(int af, const char *src, void *dst);//函数原型
函数参数:af: 你要选择哪一种协议族 IPV4 --》AF_INET 还是 IPV6--》AF_INET6src: 本地IP地址dst:将本地IP地址转为网络IP地址存储到这里
函数功能:将本地IP地址转为网络IP地址
函数返回值:成功返回0, 失败返回-1//配置方法
struct ip_mreq vmreq;
inet_pton(AF_INET, "224.0.0.10", &vmreq.imr_multiaddr); // 组播地址
inet_pton(AF_INET, "192.168.63.2", &vmreq.imr_interface); // 需要添加到组的ip
③、加入组播属性(设置套接字 可以接收组播信息)
setsockopt(socketfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &vmreq, sizeof(vmreq));
④、绑定地址
struct sockaddr_in saddr;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(atoi(argv[1]));
saddr.sin_addr.s_addr = htonl(INADDR_ANY); //htonl(INADDR_ANY) 代表 主机所有的地址
bind(socketfd, (struct sockaddr *)&saddr, sizeof(saddr));
⑤、接收数据
recvfrom(......)
(3)、组播实现程序
①、组播发送端
#include<stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>#define GROUPADDR "224.0.0.10" //组播地址
#define GROUPPORT 10000int main()
{printf("组播发送端.....\n");//1、创建UDP数据报套接字int socketfd = socket(AF_INET,SOCK_DGRAM,0);if(socketfd == -1){perror("socket error");return -1;}//2、发送数据,往组播地址(224.0.0.10 )里面发送数据struct sockaddr_in sendAddr;//IPV4地址结构体变量sendAddr.sin_family = AF_INET;sendAddr.sin_port = htons(GROUPPORT);sendAddr.sin_addr.s_addr = inet_addr(GROUPADDR);//一定是组播地址while(1){char buf[1024]={0};printf("data:");scanf("%s",buf); sendto(socketfd,buf,strlen(buf),0,( struct sockaddr *)&sendAddr,sizeof(sendAddr));}//3、关闭 close(socketfd);return 0;
}
②、组播接收端
#include<stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>#define OWNADDR "192.168.112.109" //接收端的IP地址 当前ubuntu的IP地址
#define GROUPADDR "224.0.0.10" //组播地址
#define GROUPPORT 10000int main()
{printf("组播接收端.....\n");//1、创建UDP套接字int socketfd = socket(AF_INET,SOCK_DGRAM,0);if(socketfd == -1){perror("socket error");return -1;}//2、定义组播结构体struct ip_mreq vmreq;//3、设置组播ip(初始化 组播结构体)inet_pton(AF_INET,GROUPADDR,&vmreq.imr_multiaddr); // 组播地址inet_pton(AF_INET,OWNADDR,&vmreq.imr_interface); // 需要添加到组的ip//4)加入组播属性(也就是设置这个套接字 可以接收组播信息)setsockopt(socketfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&vmreq,sizeof(vmreq));//5)绑定地址struct sockaddr_in saddr;saddr.sin_family = AF_INET;saddr.sin_port = htons(GROUPPORT);saddr.sin_addr.s_addr = htonl(INADDR_ANY); //htonl(INADDR_ANY) 代表 主机所有的地址bind(socketfd,(struct sockaddr *)&saddr,sizeof(saddr));//6)接收数据struct sockaddr_in otherAddr;int len = sizeof(struct sockaddr_in);while(1){char buf[1024]={0};recvfrom(socketfd,buf,sizeof(buf),0, (struct sockaddr *)&otherAddr,&len);printf("来自 %s:%u recv:%s\n",inet_ntoa(otherAddr.sin_addr),ntohs(otherAddr.sin_port),buf);}//关闭 close(socketfd);return 0;
}
相关文章:
网络编程 | UDP组播通信
1、什么是组播 在上一篇博客中,对UDP的广播通信进行了由浅入深的总结梳理,本文继续对UDP的知识体系进行探讨,旨在将UDP的组播通信由浅入深的讲解清楚。 组播是介于单播与广播之间,在一个局域网内,将某些主机添加到组中…...
T-SQL语言的语法
T-SQL深度解析与应用 T-SQL(Transact-SQL)是微软SQL Server使用的一种扩展SQL(结构化查询语言)。它不仅支持标准SQL的所有功能,而且增加了许多实用的扩展和特性,使得数据库的操作更加灵活和强大。本文将对…...
Java开发提效秘籍:巧用Apache Commons IO工具库
一、引言 在 Java 开发的广袤领域中,输入输出(I/O)操作宛如一座桥梁,连接着程序与外部世界,从文件的读取与写入,到网络数据的传输,I/O 操作无处不在,其重要性不言而喻。然而…...
第1章:Python TDD基础与乘法功能测试
写在前面 这本书是我们老板推荐过的,我在《价值心法》的推荐书单里也看到了它。用了一段时间 Cursor 软件后,我突然思考,对于测试开发工程师来说,什么才更有价值呢?如何让 AI 工具更好地辅助自己写代码,或许…...
web前端1--基础
(时隔数月我又来写笔记啦~) 1、下载vscode 1、官网下载:Visual Studio Code - Code Editing. Redefined 2、步骤: 1、点击同意 一直下一步 勾一个创建桌面快捷方式 在一直下一步 2、在桌面新建文件夹 拖到vscode图标上 打开v…...
.Net Core微服务入门全纪录(五)——Ocelot-API网关(下)
系列文章目录 1、.Net Core微服务入门系列(一)——项目搭建 2、.Net Core微服务入门全纪录(二)——Consul-服务注册与发现(上) 3、.Net Core微服务入门全纪录(三)——Consul-服务注…...
2024嵌入式系统的未来发展与技术洞察分享
时间如白驹过隙,不知不觉又是一年,这一年收获满满。接下来,将本年度对技术的感悟和洞察分析如下,希望对大家有所帮助。 在过去几十年里,嵌入式系统技术迅速发展,成为现代电子设备和智能硬件的核心组成部分。…...
python-44-嵌入式数据库SQLite和DuckDB
文章目录 1 SQLite1.1 世界上最流行的数据库1.1 SQLite简介1.2 插入语句1.3 查询数据1.4 更新数据1.5 删除数据2 DuckDB2.1 DuckDB简介2.2 DuckDB与Python结合使用2.2.1 创建表2.2.2 分析语句2.2.3 导出为parquet文件2.3 Windows中使用DuckDB3 参考附录1 SQLite Python的一个特…...
1.2.神经网络基础
目录 1.2.神经网络基础 1.2.1.Logistic回归 1.2.2 梯度下降算法 1.2.3 导数 1.2.4 向量化编程 1.2.5 正向传播与反向传播 1.2.6.练习 1.2.神经网络基础 1.2.1.Logistic回归 1.2.1.1.Logistic回归 逻辑回归是一个主要用于二分分类类的算法。那么逻辑回归是给定一个x ,…...
算法题目总结-双指针
文章目录 1.滑动窗口类型1.长度最小的子数组1.答案2.思路 2.无重复字符的最长子串1.答案2.思路 2.双指针类型1.盛最多水的容器1.答案2.思路 2.三数之和1.答案2.思路 1.滑动窗口类型 1.长度最小的子数组 1.答案 package com.sunxiansheng.arithmetic.day10;/*** Description:…...
人形机器人将制造iPhone!
前言 优必选机器人和富士康通过一项突破性的合作伙伴关系,正在将先进的人形机器人(如Walker S1及其升级版Walker S2)整合到制造流程中,以改变iPhone的生产方式。这一合作旨在通过提升机器人能力、优化工作流程以及实现更智能的自动…...
redis 各个模式的安装
一、Redis单机安装 1、安装gcc依赖 Redis是C语言编写的,编译需要GCC。 Redis6.x.x版本支持了多线程,需要gcc的版本大于4.9,但是CentOS7的默认版本是4.8.5。 升级gcc版本: yum -y install centos-release-scl yum -y install d…...
《王者荣耀》皮肤爬虫源码
1.爬取网页 https://pvp.qq.com/web201605/herolist.shtml 2.python代码 import requests from bs4 import BeautifulSoup import os import threading from queue import Queuedef mul(x):if not os.path.exists(x):os.mkdir(x)print("目录创建成功")else:pass h…...
学习ASP.NET Core的身份认证(基于JwtBearer的身份认证8)
为进一步测试通过请求头传递token进行身份验证,在main.htm中增加layui的数据表格组件,并调用后台服务分页显示数据,后台分页查询数据接口如下所示(测试时,直接将数据写死到代码中,没有查询数据库࿰…...
PyTorch使用教程(6)一文讲清楚torch.nn和torch.nn.functional的区别
torch.nn 和 torch.nn.functional 在 PyTorch 中都是用于构建神经网络的重要组件,但它们在设计理念、使用方式和功能上存在一些显著的区别。以下是关于这两个模块的详细区别: 1. 继承方式与结构 torch.nn torch.nn 中的模块大多数是通过继承 torch.nn…...
React的应用级框架推荐——Next、Modern、Blitz等,快速搭建React项目
在 React 企业级应用开发中,Next.js、Modern.js 和 Blitz 是三个常见的框架,它们提供了不同的特性和功能,旨在简化开发流程并提高应用的性能和扩展性。以下是它们的详解与比较: Next、Modern、Blitz 1. Next.js Next.js 是由 Ve…...
基于GRU实现股价多变量时间序列预测(PyTorch版)
前言 系列专栏:【深度学习:算法项目实战】✨︎ 涉及医疗健康、财经金融、商业零售、食品饮料、运动健身、交通运输、环境科学、社交媒体以及文本和图像处理等诸多领域,讨论了各种复杂的深度神经网络思想,如卷积神经网络、循环神经网络、生成对抗网络、门控循环单元、长短期记…...
Java创建对象有几种方式?
大家好,我是锋哥。今天分享关于【Java创建对象有几种方式?】面试题。希望对大家有帮助; Java创建对象有几种方式? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在Java中,创建对象主要有以下几种方式&…...
Vue3初学之Element Plus Dialog对话框,Message组件,MessageBox组件
Dialog的使用: 控制弹窗的显示和隐藏 <template><div><el-button click"dialogVisible true">打开弹窗</el-button><el-dialogv-model"dialogVisible"title"提示"width"30%":before-close&qu…...
基于Python机器学习的双色球数据分析与预测
python统计分析2003-2024年所有的中奖记录,通过人工智能机器学习预测双色球,个人意见,仅供参考. 声明:双色球具有随机性,任何工具无法预测。本文章仅作为技术交流,提供学习参考。本文所涉及的代码均为python之机器学习的代码。双色球为公益事…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...
深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
【JavaWeb】Docker项目部署
引言 之前学习了Linux操作系统的常见命令,在Linux上安装软件,以及如何在Linux上部署一个单体项目,大多数同学都会有相同的感受,那就是麻烦。 核心体现在三点: 命令太多了,记不住 软件安装包名字复杂&…...
C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。
1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...
