UDP 广播组播点播的区别及联系
1、网络IP地址的分类
组播地址是分类编址的IPv4地址中的D类地址,又叫多播地址,他的前四位必须是1110,所以网络地址的二进制取值范围是11100000~11101111对应的十进制为 224~~239。所以以224~239开头的网络地址都是组播地址。
组播地址的功能分类:
224.0.0.0~224.0.0.255为预留的组播地址(永久组地址)。
224.0.1.0~224.0.1.255是公用组播地址,可以用于Internet。
224.0.2.0~238.255.255.255为用户可用的组播地址(临时组地址),全网范围内有效。
239.0.0.0~239.255.255.255为本地管理组播地址,仅在特定的本地范围内有效。
组播优势:降低网络流量,减轻硬件负荷,减少冗余流量,节约带宽。
组播应用:多媒体、任何“单到多”数据发布应用。
2、单播、组播和广播的区别
组播(Multicast, 又称多播)是UDP专有的, 关于UDP的单播(Unicast), 组播, 广播(Broadcast)的区别, 网络上有张比较形象的图如下:

组播工作原理:
1)组播使用特殊的IPv4组播地址(224.0.0.0至239.255.255.255),组播地址是一种特殊的IP地址,用于标识一个组播组。
2)Internet组管理协议(IGMP)是一种用于主机加入和离开组播组的协议。主机通过发送IGMP报文来通知路由器它们希望加入或离开一个组播组。路由器根据接收到的IGMP报文来维护组播组的成员列表。
3)路由器:组播数据的传输需要路由器的支持。路由器通过使用组播路由协议(如PIM、IGMP等)来维护组播组的成员信息,并根据这些信息将组播数据转发到适当的接口上。
4)数据传输:当一个主机发送组播数据时,它将数据包发送到一个特定的组播地址。路由器根据组播地址和组员列表来确定将数据包转发到哪些接口上。只有加入了组播组的主机才会接收到组播数据。
总结:组播的原理是通过使用特定的组播地址和IGMP协议来实现多个主机之间的组播通信。路由器根据组员列表来转发组播数据,只有加入了组播组的主机才能接收到数据。组播可以提供高效的数据传输,适用于需要向多个目标主机发送相同数据的场景,如视频流、实时通信等。
3、 加入和离开组播组
3.1指令方式
加入组播组指令:sudo ip addr add 239.0.0.1 dev eth1 autojoin
离开组播组指令:sudo ip addr del 239.0.0.1/24 dev eth1 autojoin
3.2代码方式
加入组播组:加入组播组使用setsockopt设置IP_ADD_MEMBERSHIP选项。
struct ip_mreq multi_addr;
bzero(&multi_addr, sizeof(multi_addr));
multi_addr.imr_multiaddr.s_addr = inet_addr(“239.0.0.1”);
multi_addr.imr_interface.s_addr = INADDR_ANY;
setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&multi_addr, sizeof(multi_addr));
离开组播组:离开组播组使用setsockopt设置IP_DROP_MEMBERSHIP选项。
struct ip_mreq multi_addr;
bzero(&multi_addr, sizeof(multi_addr));
multi_addr.imr_multiaddr.s_addr = inet_addr(“239.0.0.1”);
multi_addr.imr_interface.s_addr = INADDR_ANY;
setsockopt(sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP, (void *)&multi_addr, sizeof(multi_addr));
4、C语言编写接收和发送udp组播数据
4.1组播数据发送
//组播发送初始化
int initUdpMultiCastSender(uint32_t localip,uint16_t localport)
{int sockfd = socket(AF_INET,SOCK_DGRAM,0);//创建套接字if (-1 == sockfd){printf("[initUdpMultiCastSender]socket fail\n");return -1;}//设置本地的组播地址和端口(注意:该port不是组播port,而是本地port)struct sockaddr_in myaddr;memset(&myaddr,0,sizeof(myaddr));myaddr.sin_family = AF_INET;myaddr.sin_port = htons(localport);myaddr.sin_addr.s_addr = localip;int bindret = bind(sockfd,(struct sockaddr *)(&myaddr),sizeof(struct sockaddr));if (-1 == bindret){perror("[initUdpMultiCastSender]bind fail\n");close(sockfd);return -1;}return sockfd;
}
//组播数据发送--注意发送的ip和port为组播ip,port
int sendUdpMultiCast(int sockfd,char *pMultiCastIp,uint16_t multicastPort,void *data,uint32_t len)
{struct sockaddr_in destAddr;destAddr.sin_family = AF_INET;destAddr.sin_addr.s_addr = inet_addr(pMultiCastIp);destAddr.sin_port = htons(multicastPort);int sendLen = sendto(sockfd,data,len,0,(struct sockaddr *)(&destAddr),sizeof(struct sockaddr));return sendLen;
}
4.2接收组播数据
int sockfd = socket(AF_INET,SOCK_DGRAM,0);if (-1 == sockfd){perror("socket fail\n");return -3;}printf("socket succ\n");struct ip_mreq mreq;memset(&mreq,0,sizeof(struct ip_mreq));mreq.imr_interface.s_addr = htonl(INADDR_ANY);mreq.imr_multiaddr.s_addr = inet_addr(pUdpMultiCastIp);//加入组int setoptret = setsockopt(sockfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(struct ip_mreq));if (-1 == setoptret){perror("setsockopt fail\n");return -4;}printf("setsockopt ip_add_membership succ\n");struct sockaddr_in peeraddr;memset(&peeraddr,0,sizeof(struct sockaddr_in));peeraddr.sin_family = AF_INET;peeraddr.sin_addr.s_addr = inet_addr(pUdpMultiCastIp);peeraddr.sin_port = htons(udpMultiCastPort);//绑定要接收的组播地址int bindRet = bind(sockfd,(struct sockaddr *)(&peeraddr),sizeof(struct sockaddr));if (-1 == bindRet){perror("bind fail\n");return -5;}printf("bind succ\n");while(1){char buffer[1024] = {0};socklen_t addrLen = sizeof(struct sockaddr);printf("ready 2 recv\n");int recvRet = recvfrom(sockfd,buffer,sizeof(buffer)-1,0,(struct sockaddr*)(&peeraddr),&addrLen);if (-1 == recvRet){perror("recvfrom fail\n");break;}printf("recvfrom succ,buffer is %s\n",buffer);}
说明:接收端的代码,整体的思路就是创建socket->加入组播(本地地址和组播地址赋值给mreq)->绑定ip,port(注意,该ip和port是组播ip和组播port)->接收数据(注意,接收的ip和port为组播ip,port)。
相关文章:
UDP 广播组播点播的区别及联系
1、网络IP地址的分类 组播地址是分类编址的IPv4地址中的D类地址,又叫多播地址,他的前四位必须是1110,所以网络地址的二进制取值范围是11100000~11101111对应的十进制为 224~~239。所以以224~239开头的网络地址都是组播地址。 组播地址的功能…...
STM32补充——IAP
0 前置知识: FLASH相关内容:前往STM32补充——FLASH STM32三种烧录方式(看看就行): 1.ISP:In System Programming(在系统编程) 执行芯片厂商的 Bootloader 程序进入 ISP 模式&…...
Jetson Xavier NX (ARM) 使用 PyTorch 安装 Open3D-ML 指南
由于 Jetson 为 ARM64 (aarch64) 的系统架构,所以不能用 pip install 直接安装,需要通过源码编译。 升级系统 JetPack 由于 Open3D-ML 目前只支持 CUDA 10.0 以及 CUDA 11.*,并且 JetPack 的 CUDA 开发环境只有10.2、11.4以及12.2࿰…...
【C++高并发服务器WebServer】-1:Linux中父子进程fork创建及关系、GDB多进程调试
本文目录 一、进程创建二、GDB多进程调试 一、进程创建 在Linux中输入man 2 fork可以查看man文档中的fork的相关函数信息。 fork的作用就是创建一个子进程。 通过fork我们可以知道,创建子进程的时候,复制父进程的信息。 我们看看翻译的man文档信息&am…...
C语言数组详解:从基础到进阶的全面解析
在C语言中,数组是一种基本的数据结构,用于存储多个相同类型的数据。数组的引入使得C语言能够高效地存储和操作大量数据。在任何一个C语言程序中,数组都发挥着极其重要的作用。无论是在算法实现、数据存储、还是在复杂程序的设计中,…...
docker的前世今生
docker来自哪里? 从我们运维部署的历史来看,宿主机从最初的物理机到虚拟机,再到docker,一步步演进到现在。技术演进其实是为了解决当前技术的痛点,那我们来看看有哪些痛点以及如何克服痛点的。 物理机 一般来说&…...
python实现施瓦茨-克里斯托费尔【全网首个】根据用户输入推测函数
上代码: from sympy import symbols, integrate, simplify from sympy.plotting import plotn int(input("n:")) if n < 2:print("Error: Must n > 2") i 0 a [] aef [] A [] x, y symbols(x y) z, w symbols(z w)while i < n…...
c语言中的数组(上)
数组的概念 数组是⼀组相同类型元素的集合; 数组中存放的是1个或者多个数据,但是数组元素个数不能为0。 数组中存放的多个数据,类型是相同的。 数组分为⼀维数组和多维数组,多维数组⼀般⽐较多⻅的是⼆维数组。 数组创建 在C语言…...
Unity3D仿星露谷物语开发25之创建时钟界面
1、目标 在时钟界面显示当前时钟信息,同时设置特殊按钮可以快速推进时间用于测试。 2、创建GameClock.cs脚本 在Assets -> Scripts -> TimeSystem目录下创建GameClock.cs脚本。 代码如下: using System.Collections; using System.Collections…...
数据结构测试题1
一、选择题: 1.若长度为n的钱性表采用顺序存储结构,删除它的第i数据元素之前,需要先依次向前移动( )个数据元素。( C ) A .n-i B.ni C.n-i-1 D.n-i1 2.在单链表中,已知q指的结点是p指的结点的直接前驱结点&am…...
android wifi AsyncChannel(WifiManager和WifiP2pManager)
AynscChannel的讲解 [Android]AsyncChannel介绍-CSDN博客 WifiP2pManager里的channel的使用理解 WifiP2pManager.java public void createGroup(Channel c, ActionListener listener) {checkChannel(c);c.mAsyncChannel.sendMessage(CREATE_GROUP, WifiP2pGroup.NETWORK_ID_PE…...
【Image Captioning】DynRefer
DynRefer是由中国科学院大学于2024年提出的用于1种用于区域级多模态任务的模型。DynRefer 通过模拟人类视觉认知过程,显著提升了区域级多模态识别能力。通过引入人眼的动态分辨率机制, 能够以同时完成区域识别、区域属性检测和区域字幕生成任务。 文章链…...
Midjourney基础-常用修饰词+权重的用法大全
用好修饰词很关键 Midjourney要用除了掌握好提示词的写法,按照上一篇《做Midjourney最好图文教程-提示词公式以及高级参数讲解》画面主体 场景氛围 主体行为 构图方式 艺术风格 图像质量。 要画出有质感的内容我们必须要掌握好“修饰词”,这些修饰…...
没有屋檐的房子-023粪堆旁边的舞蹈
爱美是天性,贫苦的农村人也一样,贫苦的时代也一样。 本世纪,广场舞在华夏大地遍地开花,甚至都传到了外面。但是广场舞这种舞蹈形式并不是互联网时代的特产,也不是电声设备日益高级和普及时代的特产,更不是大…...
基于Docker的Kafka分布式集群
目录 1. 说明 2. 服务器规划 3. docker-compose文件 kafka{i}.yaml kafka-ui.yaml 4. kafka-ui配置集群监控 5. 参数表 6. 测试脚本 生产者-异步生产: AsyncKafkaProducer1.py 消费者-异步消费: AsyncKafkaConsumer1.py 7. 参考 1. 说明 创建一个本地开发环境所需的k…...
【博客之星】年度总结:在云影与墨香中探寻成长的足迹
🐇明明跟你说过:个人主页 🔖行路有良友,便是天堂🔖 目录 一、年度回顾 1、创作历程 2、个人成长 3、个人生活与博客事业 二、技术总结 1、赛道选择 2、技术工具 3、实战项目 三、前景与展望 1、云原生未来…...
SpringBoot的Swagger配置
一、Swagger配置 1.添加依赖 <dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId><version>3.0.2</version> </dependency> 2.修改WebMvcConfig Slf4j Configurat…...
machine learning knn算法之使用KNN对鸢尾花数据集进行分类
通过导入必要的scikit-learn导入必要的库,加载给定的数据,划分测试集和训练集之后训练预测和评估即可 具体代码如下: import numpy as np from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split f…...
C语言练习(16)
猴子吃桃问题。猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个。第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半加一个。到第10天早上想再吃时,见只剩一个桃子了…...
SOAFEE 技术研讨会:汽车软件定义与自动驾驶技术探讨
在本次技术研讨会上,来自汽车与科技领域的专家们围绕汽车软件定义及自动驾驶技术展开了深入交流与探讨。从 SOAFEE 蓝图计划的创新性理念,到 Autoware 开源项目及 Open AD Kit 在实际应用中的探索,再到 Edge Workload Abstraction and Orches…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...
基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...
AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...
深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...
LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》
这段 Python 代码是一个完整的 知识库数据库操作模块,用于对本地知识库系统中的知识库进行增删改查(CRUD)操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 📘 一、整体功能概述 该模块…...
Vue ③-生命周期 || 脚手架
生命周期 思考:什么时候可以发送初始化渲染请求?(越早越好) 什么时候可以开始操作dom?(至少dom得渲染出来) Vue生命周期: 一个Vue实例从 创建 到 销毁 的整个过程。 生命周期四个…...
【C++】纯虚函数类外可以写实现吗?
1. 答案 先说答案,可以。 2.代码测试 .h头文件 #include <iostream> #include <string>// 抽象基类 class AbstractBase { public:AbstractBase() default;virtual ~AbstractBase() default; // 默认析构函数public:virtual int PureVirtualFunct…...
