当前位置: 首页 > 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;这在发行的软件来看是…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容&#xff0c;我认为是AI开发里面非常重要的内容。它在AI开发里无处不在&#xff0c;当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗"&#xff0c;或者让翻译模型 "将这段合同翻译成商务日语" 时&#xff0c;输入的这句话就是 Prompt。…...

label-studio的使用教程(导入本地路径)

文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

图表类系列各种样式PPT模版分享

图标图表系列PPT模版&#xff0c;柱状图PPT模版&#xff0c;线状图PPT模版&#xff0c;折线图PPT模版&#xff0c;饼状图PPT模版&#xff0c;雷达图PPT模版&#xff0c;树状图PPT模版 图表类系列各种样式PPT模版分享&#xff1a;图表系列PPT模板https://pan.quark.cn/s/20d40aa…...

2023赣州旅游投资集团

单选题 1.“不登高山&#xff0c;不知天之高也&#xff1b;不临深溪&#xff0c;不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别

【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而&#xff0c;传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案&#xff0c;能够实现大范围覆盖并远程采集数据。尽管具备这些优势&#xf…...

C#学习第29天:表达式树(Expression Trees)

目录 什么是表达式树&#xff1f; 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持&#xff1a; 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...

Chrome 浏览器前端与客户端双向通信实战

Chrome 前端&#xff08;即页面 JS / Web UI&#xff09;与客户端&#xff08;C 后端&#xff09;的交互机制&#xff0c;是 Chromium 架构中非常核心的一环。下面我将按常见场景&#xff0c;从通道、流程、技术栈几个角度做一套完整的分析&#xff0c;特别适合你这种在分析和改…...

Qt 事件处理中 return 的深入解析

Qt 事件处理中 return 的深入解析 在 Qt 事件处理中&#xff0c;return 语句的使用是另一个关键概念&#xff0c;它与 event->accept()/event->ignore() 密切相关但作用不同。让我们详细分析一下它们之间的关系和工作原理。 核心区别&#xff1a;不同层级的事件处理 方…...

云原生周刊:k0s 成为 CNCF 沙箱项目

开源项目推荐 HAMi HAMi&#xff08;原名 k8s‑vGPU‑scheduler&#xff09;是一款 CNCF Sandbox 级别的开源 K8s 中间件&#xff0c;通过虚拟化 GPU/NPU 等异构设备并支持内存、计算核心时间片隔离及共享调度&#xff0c;为容器提供统一接口&#xff0c;实现细粒度资源配额…...