网络编程 | 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;
}

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

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

相关文章

【无标题】微调是迁移学习吗?

是的&#xff0c;微调&#xff08;Fine-Tuning&#xff09;可以被视为一种迁移学习&#xff08;Transfer Learning&#xff09;的形式。迁移学习是一种机器学习方法&#xff0c;其核心思想是利用在一个任务上学到的知识来改进另一个相关任务的性能。微调正是通过在预训练模型的…

【HarmonyOS NAPI 深度探索12】创建你的第一个 HarmonyOS NAPI 模块

【HarmonyOS NAPI 深度探索12】创建你的第一个 HarmonyOS NAPI 模块 在本篇文章中&#xff0c;我们将一步步走过如何创建一个简单的 HarmonyOS NAPI 模块。通过这个模块&#xff0c;你将能够更好地理解 NAPI 的工作原理&#xff0c;并在你的应用中开始使用 C 与 JavaScript 的…

【电视盒子】HI3798MV300刷机教程笔记/备份遥控码修复遥控器/ADB/线刷卡刷/电视盒子安装第三方应用软件

心血来潮&#xff0c;看到电视机顶盒满天飞的广告&#xff0c;想改造一下家里的电视盒子&#xff0c;学一下网上的人刷机&#xff0c;但是一切都不知道怎么开始&#xff0c;虽然折腾了一天&#xff0c;以失败告终&#xff0c;还是做点刷机笔记。 0.我的机器 年少不会甄别&…

Python基于OpenCV和PyQt5的人脸识别上课签到系统【附源码】

博主介绍&#xff1a;✌Java老徐、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&…

【FPGA】MIPS 12条整数指令【1】

目录 修改后的仿真结果 修改后的完整代码 实现bgtz、bltz、jalr 仿真结果&#xff08;有问题&#xff09; bltz------并未跳转&#xff0c;jCe&#xff1f; 原因是该条跳转语句判断的寄存器r7&#xff0c;在该时刻并未被赋值 代码&#xff08;InstMem修改前&#xff09; i…

Java面试专题——常见面试题1

引入 本文属于专题中的常见面试题模块&#xff0c;属于面试时经常遇到的&#xff0c;适合需要面试的小伙伴做面试前复习准备用&#xff0c;后续会持续补充 1.面向对象基本特征 面向对象的基本特征是什么&#xff1f;怎么理解&#xff1f; 面向对象的基本特征是封装、继承、…

VUE实现简单留言板(Timeline+infinite scroll+Springboot+Hibernate)

先贴出效果图&#xff1a; 留言按照倒序排列。在底部的文本框内输入留言后&#xff0c;点击“留言”按钮&#xff0c;留言将保存至数据库中&#xff0c;同时刷新网页&#xff0c;新留言出现在顶部。 当滚动条到底部时&#xff0c;自动调用加载函数&#xff0c;显示更多早期留…

Java基础(3)

Java 数据类型详解 九、运算符 1. 基本运算符 Java 提供了多种运算符来执行不同的操作&#xff1a; 算术运算符&#xff1a;&#xff08;加&#xff09;、-&#xff08;减&#xff09;、*&#xff08;乘&#xff09;、/&#xff08;除&#xff09;、%&#xff08;取模&…

电力场景红外测温图像绝缘套管分割数据集labelme格式2436张1类别

数据集格式&#xff1a;labelme格式(不包含mask文件&#xff0c;仅仅包含jpg图片和对应的json文件) 图片数量(jpg文件个数)&#xff1a;2436 标注数量(json文件个数)&#xff1a;2436 标注类别数&#xff1a;1 标注类别名称:["arrester"] 每个类别标注的框数&am…

降维算法:主成分分析

主成分分析 一种常用的数据分析技术&#xff0c;主要用于数据降维&#xff0c;在众多领域如统计学、机器学习、信号处理等都有广泛应用。 主成分分析是一种通过正交变换将一组可能存在相关性的变量转换为一组线性不相关的变量&#xff08;即主成分&#xff09;的方法。这些主…

深入解析 C++17 中的 u8 字符字面量:提升 Unicode 处理能力

在现代软件开发中&#xff0c;处理多语言文本是一个常见需求&#xff0c;特别是在全球化的应用场景下。C17 标准引入的 u8 字符字面量为开发者提供了一个强大的工具&#xff0c;以更有效地处理和表示 UTF-8 编码的字符串。本文将详细探讨 u8 字符字面量的技术细节、实际应用&am…

ElasticSearch索引别名的应用

个人博客&#xff1a;无奈何杨&#xff08;wnhyang&#xff09; 个人语雀&#xff1a;wnhyang 共享语雀&#xff1a;在线知识共享 Github&#xff1a;wnhyang - Overview Elasticsearch 索引别名是一种极为灵活且强大的功能&#xff0c;它允许用户为一个或多个索引创建逻辑上…

Java高频面试之SE-15

hello啊&#xff0c;各位观众姥爷们&#xff01;&#xff01;&#xff01;本牛马baby今天又来了&#xff01;哈哈哈哈哈嗝&#x1f436; String 怎么转成 Integer 的&#xff1f;它的原理是&#xff1f; 在 Java 中&#xff0c;要将 String 转换为 Integer 类型&#xff0c;可…

2024又是一年的CSDN之旅-总结过去展望未来

一、前言 一年就这样在忙忙碌碌的工作和生活中一晃而过&#xff0c;总结今年在CSDN上发表的博客&#xff0c;也有上百篇之多&#xff0c;首先感谢CSDN这个平台&#xff0c;能让我有一个地方记录工作中的点点滴滴&#xff0c;也在上面学到了不少知识&#xff0c;解决了工作中遇到…

c86机器安装nvaid显卡驱动报错:ERROR:Unable to load the kernel module ‘nvidia.ko‘.

背景&#xff1a; 最近小伙伴要去北京甲方现场搭建我们的AI编码服务&#xff0c;需要使用GPU机器跑大模型&#xff0c;根据现场提供的信息是2台C86的机器&#xff0c;显卡够够的&#xff0c;但是现场是内网环境&#xff0c;因此&#xff0c;需要先准备好需要的安装包&#xff…

LeetCode 热题 100_实现 Trie (前缀树)(54_208_中等_C++)(图;前缀树;字典树)

[TOC](LeetCode 热题 100_实现 Trie (前缀树)&#xff08;54_208&#xff09;) 题目描述&#xff1a; Trie&#xff08;发音类似 “try”&#xff09;或者说 前缀树 是一种树形数据结构&#xff0c;用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景&…

【Maui】视图界面与数据模型绑定

文章目录 前言一、问题描述二、解决方案三、软件开发&#xff08;源码&#xff09;3.1 创建模型3.2 视图界面3.3 控制器逻辑层 四、项目展示 前言 .NET 多平台应用 UI (.NET MAUI) 是一个跨平台框架&#xff0c;用于使用 C# 和 XAML 创建本机移动和桌面应用。 使用 .NET MAUI&…

从 Spark 到 StarRocks:实现58同城湖仓一体架构的高效转型

作者&#xff1a;王世发&#xff0c;吴艳兴等&#xff0c;58同城数据架构部 导读&#xff1a; 本文介绍了58同城在其数据探查平台中引入StarRocks的实践&#xff0c;旨在提升实时查询性能。在面对传统Spark和Hive架构的性能瓶颈时&#xff0c;58同城选择StarRocks作为加速引擎&…

探秘 Linux 进程状态:解锁系统运行的密码

&#x1f31f; 快来参与讨论&#x1f4ac;&#xff0c;点赞&#x1f44d;、收藏⭐、分享&#x1f4e4;&#xff0c;共创活力社区。&#x1f31f; &#x1f6a9;用通俗易懂且不失专业性的文字&#xff0c;讲解计算机领域那些看似枯燥的知识点&#x1f6a9; 在 Linux 系统…

深度学习-89-大语言模型LLM之AI应用开发的基本概念

文章目录 1 什么是智能体(Agent)2 什么是大语言模型(LLM)2.1 LLM的训练及使用2.2 Transformer架构2.3 基于LLM的Agent框架3 什么是检索增强生成(RAG)3.1 RAG是什么3.2 生成式AI应用开发3.3 RAG的整体流程3.4 RAG技术3.4.1 简单RAG(Simple RAG)3.4.2 校正RAG(Corrective RAG)3.4…