当前位置: 首页 > news >正文

C++网络编程之多播

概述

        在移动互联网时代,随着多媒体应用的日益普及,如何高效地将数据传输给多个接收者成为了网络通信领域的一个重要课题。多播(英文为Multicast)作为一种高效的网络通信方式,可以将数据同时发送到多个接收者,而不需要为每个接收者单独建立连接。

        与单播(英文为Unicast)相比,多播减少了网络中的数据包复制,从而降低了带宽消耗。与广播(英文为Broadcast)相比,多播仅向那些明确表示希望接收数据的主机发送数据,而不是局域网内的所有主机。多播技术因其高效的数据传输特性,特别适合视频会议、在线教育、远程培训、直播服务等应用场景。

        在IPv4地址中,224.0.0.0至239.255.255.255被保留用于多播。IPv6则有更大的多播地址空间,从FF00::/8开始。

多播组

        多播不是直接面向特定主机的,而是面向一组主机。任何想要接收特定多播组数据的主机,都可以加入该组。当数据发送到一个特定的多播地址时,所有加入了这个多播组的主机都能接收到这些数据。多播组的成员身份是动态的,设备可以根据需要加入或离开多播组。

        1、加入多播组。要让设备能够接收多播数据,首先需要告诉网络层该设备希望加入某个多播组,这是通过设置套接字选项来实现的。

        (1)对于IPv4,使用setsockopt函数设置IP_ADD_MEMBERSHIP选项。

        (2)对于IPv6,使用setsockopt函数设置IPV6_JOIN_GROUP选项。

        具体如何加入,可参考下面的示例代码。

// 对于IPv4
struct ip_mreq mreq;
// 多播地址
mreq.imr_multiaddr.s_addr = inet_addr("224.0.0.1");
// 任意接口,也可指定某个特定接口
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq)) < 0)
{cout << "加入多播组失败" << endl;
}// 对于IPv6
struct ipv6_mreq mreq6;
// 多播地址
mreq6.ipv6mr_multiaddr = in6addr_any;
// 任意接口
mreq6.ipv6mr_interface = 0;
if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq6, sizeof(mreq6)) < 0)
{cout << "加入多播组失败" << endl;
}

        2、离开多播组。当不再需要接收多播数据时,设备可以离开多播组以释放资源。

        (1)对于IPv4,使用setsockopt函数设置IP_DROP_MEMBERSHIP选项。

        (2)对于IPv6,使用setsockopt函数设置IPV6_LEAVE_GROUP选项。

        具体如何离开,可参考下面的示例代码。

// 对于IPv4
if (setsockopt(sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char *)&mreq, sizeof(mreq)) < 0)
{cout << "离开多播组失败" << endl;
}// 对于IPv6
if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &mreq6, sizeof(mreq6)) < 0)
{cout << "离开多播组失败" << endl;
}

        3、成员资格查询。在某些情况下,我们可能需要查询一个网络接口是否已经加入了特定的多播组。

        (1)对于IPv4,使用setsockopt函数设置IP_MULTICAST_IF选项。

        (2)对于IPv6,使用setsockopt函数设置IPV6_MULTICAST_IF选项。

        具体如何查询,可参考下面的示例代码。

// 对于IPv4,查询成员资格
struct ip_mreqn mreqn;
socklen_t len = sizeof(mreqn);
if (getsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_IF, &mreqn, &len) < 0)
{cout << "获取多播接口失败" << endl;
}
else
{// 判断是否加入了多播组if (mreqn.mr_multiaddr.s_addr == INADDR_ANY){cout << "没有加入任何多播组" << endl;}else{cout << "已加入多播组, 地址为: " << inet_ntoa(mreqn.mr_multiaddr) << endl;}
}// 对于IPv6,查询成员资格
struct ipv6_mreq mreq6;
socklen_t len = sizeof(mreq6);
if (getsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &mreq6, &len) < 0)
{cout << "获取多播接口失败" << endl;
}
else
{// 判断是否加入了多播组if (memcmp(&mreq6.ipv6mr_multiaddr, &in6addr_any, sizeof(in6addr_any)) == 0){cout << "没有加入任何多播组" << endl;}else{char pszAddr[INET6_ADDRSTRLEN];inet_ntop(AF_INET6, &mreq6.ipv6mr_multiaddr, pszAddr, sizeof(pszAddr));cout << "已加入多播组, 地址为: " << pszAddr << endl;}
}

收发数据

        发送多播数据与发送单播数据类似,只需要指定多播地址作为目标即可。根据多播的特性可以知道,发送方并不关心哪些主机实际上接收了数据。具体如何发送,可参考下面的示例代码。

// 设置多播地址
struct sockaddr_in dest;
dest.sin_family = AF_INET;
dest.sin_port = htons(PORT);
inet_pton(AF_INET, "224.0.0.1", &dest.sin_addr);// 发送数据
const char *pszMsg = "Hello, Hope Wisdom";
sendto(sockfd, pszMsg, strlen(pszMsg), 0, (struct sockaddr *)&dest, sizeof(dest));

        接收多播数据同样与接收单播数据相似,但需要绑定到一个特定的端口,并且通常绑定到一个任意IP地址(INADDR_ANY)。这意味着,我们可以从任何网络接口接收数据。具体如何接收,可参考下面的示例代码。

struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = INADDR_ANY;// 绑定套接字到端口
bind(sockfd, (struct sockaddr *)&addr, sizeof(addr));// 接收数据
char pszBuf[BUFSIZE] = {0};
int nRecvedBytes = recvfrom(sockfd, pszBuf, BUFSIZE, 0, NULL, NULL);
cout << "Recved data: " << pszBuf<< endl;

相关文章:

C++网络编程之多播

概述 在移动互联网时代&#xff0c;随着多媒体应用的日益普及&#xff0c;如何高效地将数据传输给多个接收者成为了网络通信领域的一个重要课题。多播&#xff08;英文为Multicast&#xff09;作为一种高效的网络通信方式&#xff0c;可以将数据同时发送到多个接收者&#xff0…...

不只是请求和响应:使用Fiddler抓包URL和Method全指南(中)

欢迎浏览高耳机的博客 希望我们彼此都有更好的收获 感谢三连支持! 不只是请求和响应&#xff1a;使用Fiddler抓包HTTP协议全指南(上)-CSDN博客https://blog.csdn.net/Chunfeng6yugan/article/details/144005872?spm1001.2014.3001.5502 &#x1f649;在(上)篇博客中&#xf…...

学习threejs,使用设置normalMap法向量贴图创建更加细致的凹凸和褶皱

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️THREE.MeshPhongMaterial高…...

Hive构建日搜索引擎日志数据分析系统

1.数据预处理 根据自己或者学校系统预制的数据 使用less sogou.txt可查看 wc -l sogou.txt 能够查看总行数 2.数据扩展部分 我的数据位置存放在 /data/bigfiles 点击q退出 将一个文件的内容传递到另一个目录文件下 原数据在 /data/bigfiles ->传递 到/data/workspac…...

Vue 3 defineModel: 简化组件的双向绑定

1. 引言 在 Vue 3.4 版本中,引入了一个新的组合式 API 函数 defineModel。这个函数大大简化了自定义组件中实现 v-model 的过程,使得创建具有双向绑定功能的组件变得更加直观和简洁。 © ivwdcwso (ID: u012172506) 2. defineModel 的基本概念 defineModel 是一个宏,它简…...

【Flutter】搭建Flutter开发环境,安卓开发

Flutter是谷歌开源的一个跨平台开发的框架&#xff0c;方便好用&#xff0c;这里以Windows 上构建 Flutter Android 应用为例&#xff0c;记录下我搭建环境时碰到的一些问题以及解决。 第一步&#xff1a;参考官网&#xff1a;开发 Android 应用 | Flutter 中文文档 - Flutter …...

Linux中的共享内存

在Linux中&#xff0c;共享内存是一种高效的进程间通信&#xff08;IPC&#xff09;机制&#xff0c;允许多个进程共享一块内存区域&#xff0c;从而实现数据的快速传递和共享。它的特点是可以直接访问共享的内存&#xff0c;无需额外的拷贝操作&#xff0c;因此速度非常快。 共…...

SpringBoot中忽略实体类中的某个属性不返回给前端的方法

使用Jackson的方式&#xff1a; //第一种方式&#xff0c;使用JsonIgnore注解标注在属性上&#xff0c;忽略指定属性 public class PropertyDTO {JsonProperty("disable")private Integer disable;JsonProperty("placeholder")private String placeholde…...

ubuntu 安装proxychains

在Ubuntu上安装Proxychains&#xff0c;你可以按照以下步骤操作&#xff1a; 1、更新列表 sudo apt-update 2、安装Proxychains sudo apt-get install proxychains 3、安装完成后&#xff0c;你可以通过编辑/etc/proxychains.conf文件来配置代理规则 以下是一个简单的配置示例&…...

pytorch四种单机多卡分布式训练方法

文章目录 1、原生pytorch&#xff08;mp.spawn)2、pytorch ddp (torchrun)3、lightning fabric4、Hugging Face Accelerate4、总结与对比4.1 mp.spawn4.2 torchrun4.3 Lightning Fabric4.4 Hugging face accelerate pytorch 分布式训练的四种方法。 我将会产生一份伪数据0到19共…...

archlinux 触摸板手势配置

文章目录 [toc]libinput-gestures安装 libinput-gestures加入 input 组创建配置文件可用手势 启动 libinput-gestures停止 libinput-gestures自启动 libinput-gestures Touchpad Synapticssynaptics.4 在 /etc/X11/xorg.conf.d/ 目录下会有默认的触摸板配置文件&#xff0c;如果…...

djinn:1 靶场学习小记

一、测试环境&#xff1a; kail攻击机&#xff1a;Get Kali | Kali Linux 靶场镜像&#xff1a;https://download.vulnhub.com/djinn/djinn.ova 描述&#xff1a; 该机器与 VirtualBox 和 VMWare 兼容。DHCP 将自动分配一个 IP。您将在登录屏幕上看到 IP。您必须找到并读取分…...

kafka消费者组和分区数之间的关系是怎样的?

消费者组和分区数之间的关系决定了Kafka中消息的消费方式和负载均衡。合理配置分区数和消费者数量对于优化Kafka的性能和资源利用率至关重要。以下是这种关系的几个关键点&#xff1a; 一个分区只能被同一组的一个消费者消费&#xff1a;这是为了保证消息的顺序性。在同一个消费…...

【go】查询某个依赖是否存在于这个代理

1. 使用 go list 命令 go list -m -versions github.com/gin-gonic/gin 如果模块存在&#xff0c;该命令会返回模块及其可用版本&#xff1a; github.com/gin-gonic/gin v1.7.0 v1.7.1 v1.8.0如果模块不存在或无法找到&#xff0c;会返回错误。 2. 使用 curl 查询代理服务 …...

如何从postman中导出所有集合Collection

项目场景&#xff1a; 有时候需要备份或迁移到其他平台&#xff0c;我们需要在postman中将这些集合数据导出。导出 Postman 集合是为了备份、团队共享或平台迁移等目的的重要步骤。此过程可分为导出单个集合和批量导出所有集合两部分&#xff0c;确保已保存和更新集合后&#x…...

在 Spring Boot 中实现多种方式登录(用户名、手机号、邮箱等)的不正经指南

欢迎来到一场技术与幽默交织的冒险&#xff01;今天&#xff0c;我们将跳进 Spring Boot 的世界&#xff0c;探索如何通过 用户名、手机号、邮箱 等多种方式实现登录。想象一下&#xff0c;用户在登录时可以随心所欲地选择——就像你今天早上纠结到底是要喝美式咖啡还是拿铁&am…...

.NET平台用C#添加动作到PDF文档

使用C#语言在.NET框架下向PDF文档中添加动作&#xff0c;不仅能够提升文档的交互性和用户体验&#xff0c;还能够在自动化工作流中发挥关键作用&#xff0c;例如自动跳转至特定页面、链接外部资源或播放音频资源等操作。这种能力使得开发者能够根据具体需求定制PDF文档的互动操…...

大数据治理:概念、框架与实践应用

摘要: 随着大数据时代的到来,数据量呈爆炸式增长,数据来源和类型日益多样化。大数据治理作为确保数据质量、安全性、合规性以及有效利用数据资产的关键领域,已成为企业和组织在数字化转型过程中面临的重要挑战和机遇。本文深入探讨了大数据治理的概念,详细阐述了其涵盖的主…...

Vue.observable 全解析:Observable 是什么及使用场景剖析

Vue.observable 详解 Vue.observable 是 Vue 2.x 中的一个 API,用于将普通对象转化为响应式对象,类似于 Vue 组件中的 data 对象,可以实现数据的双向绑定。它允许你将任何普通对象转化为 Vue 响应式系统管理的对象,使得该对象的属性变化时能够自动触发视图更新。 什么是 …...

MySQL基础知识大总结

一&#xff0c;介绍 数据库是什么&#xff0c;我们在学习其他编程语言的时候会使用数组呀&#xff0c;链表&#xff0c;二叉树等等一些数据结构来存储我们的数据&#xff0c;但是大家有没有发现我们一旦关闭程序&#xff0c;所有的数据都没有了&#xff0c;这在发行的软件来看是…...

<6>-MySQL表的增删查改

目录 一&#xff0c;create&#xff08;创建表&#xff09; 二&#xff0c;retrieve&#xff08;查询表&#xff09; 1&#xff0c;select列 2&#xff0c;where条件 三&#xff0c;update&#xff08;更新表&#xff09; 四&#xff0c;delete&#xff08;删除表&#xf…...

(二)原型模式

原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

网络编程(UDP编程)

思维导图 UDP基础编程&#xff08;单播&#xff09; 1.流程图 服务器&#xff1a;短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

算法岗面试经验分享-大模型篇

文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer &#xff08;1&#xff09;资源 论文&a…...

Leetcode33( 搜索旋转排序数组)

题目表述 整数数组 nums 按升序排列&#xff0c;数组中的值 互不相同 。 在传递给函数之前&#xff0c;nums 在预先未知的某个下标 k&#xff08;0 < k < nums.length&#xff09;上进行了 旋转&#xff0c;使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…...

【WebSocket】SpringBoot项目中使用WebSocket

1. 导入坐标 如果springboot父工程没有加入websocket的起步依赖&#xff0c;添加它的坐标的时候需要带上版本号。 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dep…...

AxureRP-Pro-Beta-Setup_114413.exe (6.0.0.2887)

Name&#xff1a;3ddown Serial&#xff1a;FiCGEezgdGoYILo8U/2MFyCWj0jZoJc/sziRRj2/ENvtEq7w1RH97k5MWctqVHA 注册用户名&#xff1a;Axure 序列号&#xff1a;8t3Yk/zu4cX601/seX6wBZgYRVj/lkC2PICCdO4sFKCCLx8mcCnccoylVb40lP...

接口 RESTful 中的超媒体:REST 架构的灵魂驱动

在 RESTful 架构中&#xff0c;** 超媒体&#xff08;Hypermedia&#xff09;** 是一个核心概念&#xff0c;它体现了 REST 的 “表述性状态转移&#xff08;Representational State Transfer&#xff09;” 的本质&#xff0c;也是区分 “真 RESTful API” 与 “伪 RESTful AP…...

linux设备重启后时间与网络时间不同步怎么解决?

linux设备重启后时间与网络时间不同步怎么解决&#xff1f; 设备只要一重启&#xff0c;时间又错了/偏了&#xff0c;明明刚刚对时还是对的&#xff01; 这在物联网、嵌入式开发环境特别常见&#xff0c;尤其是开发板、树莓派、rk3588 这类设备。 解决方法&#xff1a; 加硬件…...