socket之UDP组播(多播)

组播也可以称之为多播这也是 UDP 的特性之一。组播是主机间一对多的通讯模式,是一种允许一个或多个组播源发送同一报文到多个接收者的技术。组播源将一份报文发送到特定的组播地址,组播地址不同于单播地址,它并不属于特定某个主机,而是属于一组主机。一个组播地址表示一个群组,需要接收组播报文的接收者都加入这个群组。

广播只能在局域网访问内使用,组播既可以在局域网中使用,也可以用于广域网
在发送广播消息的时候,连接到局域网的客户端不管想不想都会接收到广播数据,组播可以控制发送端的消息能够被哪些接收端接收,更灵活和人性化。
广播使用的是广播地址,组播需要使用组播地址。
广播和组播属性默认都是关闭的,如果使用需要通过 setsockopt () 函数进行设置。
组播需要使用组播地址,在 IPv4 中它的范围从 224.0.0.0 到 239.255.255.255,并被划分为局部链接多播地址、预留多播地址和管理权限多播地址三类

224.0.0.0 ~ 224.0.0.255: 局部链接多播地址:是为路由协议和其它用途保留的地址,
只能用于局域网中,路由器是不会转发的地址 224.0.0.0 不能用,是保留地址
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: 为本地管理组播地址,仅在特定的本地范围内有效

组播地址不属于任何服务器或个人,它有点类似一个微信群号,任何成员(组播源)往微信群(组播 IP)发送消息(组播数据),这个群里的成员(组播接收者)都会接收到此消息。

组播应用

点对多点应用
点对多点应用是指一个发送者,多个接收者的应用形式,这是最常见的多播应用形式。典型的应用包括:媒体广播、媒体推送、信息缓存、事件通知和状态监视等。

多点对点应用
多点对点应用是指多个发送者,一个接收者的应用形式。通常是双向请求响应应用,任何一端(多点或点)都有可能发起请求。典型应用包括:资源查找、数据收集、网络竞拍、信息询问等。

多点对多点应用
多点对多点应用是指多个发送者和多个接收者的

应用形式。通常,每个接收者可以接收多个发送者发送的数据,同时,每个发送者可以把数据发送给多个接收者。典型应用包括:多点会议、资源同步、并行处理、协同处理、远程学习、讨论组、分布式交互模拟(DIS)、多人游戏等

设置组播属性
如果使用组播进行数据的传输,不管是消息发送端还是接收端,都需要进行相关的属性设置,设置函数使用的是同一个,即:setsockopt(),函数原型如下:

int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);

发送端
发送组播消息的一端需要设置组播属性,具体的设置方式如下:

/*
struct in_addr
{in_addr_t s_addr;	// unsigned int
};
*//*
函数:setsockopt
描述:配置发送端UDP组播属性
参数:sockfd:	用于 UDP 通信的套接字level:		套接字级别,设置组播属性需要将该参数指定为:IPPTOTO_IPoptname: 	套接字选项名,设置组播属性需要将该参数指定为:IP_MULTICAST_IFoptval:	设置组播属性,这个指针需要指向一个 struct in_addr{} 类型的结构体地址,这个结构体地址用于存储组播地址,并且组播 IP 地址的存储方式是大端的。optlen:optval 指针指向的内存大小,即:sizeof(struct in_addr)返回值:函数调用成功返回 0,调用失败返回 - 1	
*/struct in_addr opt;// 将组播地址初始化到这个结构体成员中即可inet_pton(AF_INET, GROUP_IP, &opt.s_addr);setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &opt, sizeof(opt));

接收端
因为一个组播地址表示一个群组,所以需要接收组播报文的接收者都加入这个群组,和想要接收群消息就必须要先入群是一个道理。加入到这个组播群组的方式如下:

/*
struct in_addr
{in_addr_t s_addr;	// unsigned int
};struct ip_mreqn
{struct in_addr imr_multiaddr;   // 组播地址/多播地址struct in_addr imr_address;     // 本地地址int   imr_ifindex;              // 网卡的编号, 每个网卡都有一个编号
};
// 必须通过网卡名字才能得到网卡的编号: 可以通过 ifconfig 命令查看网卡名字
#include <net/if.h>
// 将网卡名转换为网卡的编号, 参数是网卡的名字, 比如: "ens33"
// 返回值就是网卡的编号
unsigned int if_nametoindex(const char *ifname);
*//*
函数:setsockopt
描述:配置接收端UDP组播属性
参数:sockfd:基于 udp 的通信的套接字level:套接字级别,加入到多播组该参数需要指定为:IPPTOTO_IPoptname:套接字选项名,加入到多播组该参数需要指定为:IP_ADD_MEMBERSHIPoptval:加入到多播组,这个指针应该指向一个 struct ip_mreqn{} 类型的结构体地址optlen:optval 指向的内存大小,即:sizeof(struct ip_mreqn)
*/struct ip_mreqn opt;// 要加入到哪个多播组, 通过组播地址来区分inet_pton(AF_INET, GROUP_IP, &opt.imr_multiaddr.s_addr);opt.imr_address.s_addr = htonl(INADDR_ANY);opt.imr_ifindex = if_nametoindex("ens33");setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &opt, sizeof(opt));

组播通信流程
发送组播消息的一端需要将数据发送到组播地址和固定的端口上,想要接收组播消息的终端需要绑定对应的固定端口然后加入到组播的群组,最终就可以实现数据的共享。

发送端代码

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>#define GROUP_IP "224.0.1.0"
//#define GROUP_IP "239.0.1.10"int main()
{// 1. 创建通信的套接字int fd = socket(AF_INET, SOCK_DGRAM, 0);if(fd == -1){perror("socket");exit(0);}// 2. 设置组播属性 (经测试可以不设置发送端组播属性也能正常发送)struct in_addr opt;// 将组播地址初始化到这个结构体成员中即可inet_pton(AF_INET, GROUP_IP, &opt.s_addr);setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &opt, sizeof(opt));char buf[1024];char sendaddrbuf[64];socklen_t len = sizeof(struct sockaddr_in);struct sockaddr_in sendaddr;struct sockaddr_in cliaddr;cliaddr.sin_family = AF_INET;cliaddr.sin_port = htons(9999); // 接收端需要绑定9999端口// 发送组播消息, 需要使用组播地址, 和设置组播属性使用的组播地址一致就可以inet_pton(AF_INET, GROUP_IP, &cliaddr.sin_addr.s_addr);// 3. 通信int num = 0;while(1){memset(buf, 0, sizeof(buf));sprintf(buf, "hello, client...%d\n", num++);// 数据广播sendto(fd, buf, strlen(buf)+1, 0, (struct sockaddr*)&cliaddr, len);printf("发送的组播的数据: %s\n", buf);memset(buf, 0, sizeof(buf));recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&sendaddr, &len);printf("sendaddr:%s, prot:%d\n", inet_ntop(AF_INET, &sendaddr.sin_addr.s_addr,  sendaddrbuf, sizeof(sendaddrbuf)),  sendaddr.sin_port);printf("接收到的组播消息: %s\n", buf);}close(fd);return 0;
}

接收端代码

#define GROUP_IP "224.0.1.0"
//#define GROUP_IP "239.0.1.10"int main()
{// 1. 创建通信的套接字int fd = socket(AF_INET, SOCK_DGRAM, 0);if(fd == -1){perror("socket");exit(0);}// 2. 通信的套接字和本地的IP与端口绑定struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(9999);    // 大端addr.sin_addr.s_addr = htonl(INADDR_ANY);  // 0.0.0.0int ret = bind(fd, (struct sockaddr*)&addr, sizeof(addr));if(ret == -1){perror("bind");exit(0);}// 3. 加入到多播组#if 0 //使用struct ip_mreqn或者 struct ip_mreq 设置接收端组播属性都可以正常接收struct ip_mreqn opt;// 要加入到哪个多播组, 通过组播地址来区分inet_pton(AF_INET, GROUP_IP, &opt.imr_multiaddr.s_addr);opt.imr_address.s_addr = htonl(INADDR_ANY);opt.imr_ifindex = if_nametoindex("ens33");setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &opt, sizeof(opt));#elsestruct ip_mreq mreq; // 多播地址结构体mreq.imr_multiaddr.s_addr=inet_addr(GROUP_IP);mreq.imr_interface.s_addr = htonl(INADDR_ANY);	ret=setsockopt(fd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq));#endifchar buf[1024];char sendaddrbuf[64];socklen_t len = sizeof(struct sockaddr_in);struct sockaddr_in sendaddr;// 3. 通信while(1){// 接收广播消息memset(buf, 0, sizeof(buf));// 阻塞等待数据达到recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&sendaddr, &len);printf("sendaddr:%s, prot:%d\n", inet_ntop(AF_INET, &sendaddr.sin_addr.s_addr,  sendaddrbuf, sizeof(sendaddrbuf)),  sendaddr.sin_port);printf("接收到的组播消息: %s\n", buf);sendto(fd, buf, strlen(buf)+1, 0, (struct sockaddr *)&sendaddr, len);}close(fd);return 0;
}

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

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

相关文章

测试必备:网站崩溃原因大揭秘!12种常见问题一网打尽

网站崩溃是研发团队最怕看到的情况&#xff0c;但是由于种种原因却时常出现&#xff0c;作为测试人员&#xff0c;我们更应该比一般人了解网站崩溃的原因及排查方法&#xff0c;这是我们测试工作的重要一环。接下来我就谈谈12种常见的网站崩溃原因以及如何跟踪和解决它们。 你的…

【JavaWeb】Day33.MySQL概述

什么是数据库 数据库&#xff1a;英文为 DataBase&#xff0c;简称DB&#xff0c;它是存储和管理数据的仓库。 像我们日常访问的电商网站京东&#xff0c;企业内部的管理系统OA、ERP、CRM这类的系统&#xff0c;以及大家每天都会刷的头条、抖音类的app&#xff0c;那这些大家所…

黑马Seata入门到实战教程(学习笔记)

Seata CAP理论 BASE理论 XA AT TCC sage模式 缺点&#xff1a;数据隔离性安全问题 四种模式对比

智慧乡村建设探索:数字乡村引领农村发展新方向

目录 一、智慧乡村建设的内涵与意义 二、数字乡村的发展现状 三、数字乡村引领农村发展的新方向 &#xff08;一&#xff09;推动农业现代化&#xff0c;提升农业生产效率 &#xff08;二&#xff09;培育农村新业态&#xff0c;促进农村产业升级 &#xff08;三&#xf…

SpringCloud Alibaba @SentinelResource 注解

一、前言 接下来是开展一系列的 SpringCloud 的学习之旅&#xff0c;从传统的模块之间调用&#xff0c;一步步的升级为 SpringCloud 模块之间的调用&#xff0c;此篇文章为第十五篇&#xff0c;即介绍 SpringCloud Alibaba 的 SentinelResource 注解。 二、简介 这个注解用于标…

解析《天道》中丁元英的五步商业运作思路

我国商战题材的电视剧中哪部最为经典&#xff1f;小马识途营销顾问认为那一定是《天道》&#xff0c;《天道》对人物的刻画非常精准&#xff0c;对人性的描写鞭辟入里&#xff0c;看过之后都会被其震撼&#xff0c;因此它不仅是一部电视剧&#xff0c;更是一部可以给人们带来商…

Databend 开源周报第 138 期

Databend 是一款现代云数仓。专为弹性和高效设计&#xff0c;为您的大规模分析需求保驾护航。自由且开源。即刻体验云服务&#xff1a;https://app.databend.cn 。 Whats On In Databend 探索 Databend 本周新进展&#xff0c;遇到更贴近你心意的 Databend 。 支持多表插入 …

位运算-201. 数字范围按位与,137. 只出现一次的数字 II(总结此类)

给你两个整数 left 和 right &#xff0c;表示区间 [left, right] &#xff0c;返回此区间内所有数字 按位与 的结果&#xff08;包含 left 、right 端点&#xff09;。 示例 1&#xff1a; 输入&#xff1a;left 5, right 7 输出&#xff1a;4 示例 2&#xff1a; 输入&…

鸿蒙ArkUI开发实战:制作一个【简单计数器】

构建第一个页面 使用文本组件 工程同步完成后&#xff0c;在 Project 窗口&#xff0c;点击 entry > src > main > ets > pages &#xff0c;打开 Index.ets 文件&#xff0c;可以看到页面由 Row 、 Column 、 Text 组件组成。 index.ets 文件的示例如下&#xff1…

基于java+springboot+vue实现的健身房管理系统(文末源码+Lw)23-223

摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装健身房管理系统软件来发挥其高效地信息处理的作用&#xf…

测开面经(pytest测试案例,接口断言,多并发断言)

pytest对用户登录接口进行自动化脚本设计 a. 创建一个名为"test_login.py"的测试文件&#xff0c;编写以下测试脚本 import pytest import requests# 测试用例1&#xff1a;验证登录成功的情况 # 第一个测试用例验证登录成功的情况&#xff0c;发送有效的用户名和密…

戴维贝拉×实在智能丨RPA助力商家线上线下一体化运营,关键指标可随时查看!

戴维贝拉&#xff08;dave&bella&#xff09;创立于2011年&#xff0c;是杭州日冠服饰有限公司旗下婴幼服饰品牌&#xff0c;至今已立足服装业10余年。2012年&#xff0c;戴维贝拉就已经成为电商销售国内前十的品牌。2021年双十一&#xff0c;戴维贝拉再次以傲人的战绩稳居…

如何实现无感刷新(附前后端实现)?

无感刷新的核心思路&#xff1a; 无感刷新机制的目的是在用户不知情的情况下&#xff0c;自动更新其认证令牌&#xff08;通常是Access Token&#xff09;&#xff0c;以保证用户的会话不会中断。这通常涉及到两种类型的令牌&#xff1a; Access Token&#xff1a;它是用户进行…

鲁大师2024年手机Q1季报:骁龙天玑高端博弈,AI已成不可逆的大趋势

其实能够很明显的感觉到&#xff0c;2024年的智能手机Q1市场&#xff0c;恢复了近几年少有的那种激情和热闹&#xff0c;AI的到来&#xff0c;让疲于奔命在性能、影像、系统、生态之外的手机厂商们终于看到了新的发展方向。 当然&#xff0c;作为近几年少有的&#xff0c;真正能…

JAVAEE——文件IO

文章目录 文件的概念什么是文件&#xff1f;树型结构组织 和 目录文件路径相对路径绝对路径 文件的分类文件的权限 文件读写IO API字符流操作API 警告字节流操作APIInputStreamOutputStream 文件的概念 什么是文件&#xff1f; 我们先来理解一下什么是文件&#xff0c;那么想…

软件安全评估之设计评审入门(上)

壹 基础概念 在软件开发生命周期&#xff08;Software Development Life Cycle&#xff0c;简称SDLC&#xff09;中&#xff0c;设计评审&#xff08;Design Review&#xff09;是一个关键的阶段&#xff0c;旨在确保软件设计满足项目需求和目标&#xff0c;并且能够高效、可靠…

01 _ 分布式缘何而起:从单兵,到游击队,到集团军

这里先来聊聊什么是分布式。 与其直接用些抽象、晦涩的技术名词去给分布式下一个定义&#xff0c;还不如从理解分布式的发展驱动因素开始&#xff0c;我们一起去探寻它的本质&#xff0c;自然而然地也就清楚它的定义了。 这里将介绍分布式的起源&#xff0c;是如何从单台计算…

聚道云连接器打通红圈CRM和金蝶云星辰,赋能环境科技公司数字化转型

一、客户介绍 某环境科技有限公司是一家专注于环保科技领域的领先企业&#xff0c;致力于为客户提供全方位的环境解决方案。公司拥有一支经验丰富、技术精湛的团队&#xff0c;不断推动环保技术的创新与应用。作为业内的佼佼者&#xff0c;该公司在环境治理、资源回收和节能减…

深度学习理论基础(四)Parser命令行参数模块

学习目录&#xff1a; 深度学习理论基础&#xff08;一&#xff09;Python及Torch基础篇 深度学习理论基础&#xff08;二&#xff09;深度神经网络DNN 深度学习理论基础&#xff08;三&#xff09;封装数据集及手写数字识别 深度学习理论基础&#xff08;四&#xff09;Parse…

Datax,hbase与mysql数据相互同步

参考文章&#xff1a;datax mysql 和hbase的 相互导入 目录 0、软件版本说明 1、hbase数据同步至mysql 1.1、hbase数据 1.2、mysql数据 1.3、json脚本&#xff08;hbase2mysql.json&#xff09; 1.4、同步成功日志 2、mysql数据同步至hbase 1.1、hbase数据 1.2、mysql…