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

3步搞定浏览器脚本:Greasy Fork小白也能懂的终极指南

3步搞定浏览器脚本&#xff1a;Greasy Fork小白也能懂的终极指南 【免费下载链接】greasyfork An online repository of user scripts. 项目地址: https://gitcode.com/gh_mirrors/gr/greasyfork 你是否厌倦了网页上烦人的广告&#xff1f;想要自动填充表单、一键下载视…...

5分钟掌握终极资源下载神器:res-downloader跨平台智能嗅探工具

5分钟掌握终极资源下载神器&#xff1a;res-downloader跨平台智能嗅探工具 【免费下载链接】res-downloader 资源下载器、网络资源嗅探&#xff0c;支持微信视频号下载、网页抖音无水印下载、网页快手无水印视频下载、酷狗音乐下载等网络资源拦截下载! 项目地址: https://git…...

Comsol模拟混凝土中水分传递 低气压下水分转移引起的水泥浆龄期微观结构变化 低气压(AP)...

Comsol模拟混凝土中水分传递 低气压下水分转移引起的水泥浆龄期微观结构变化 低气压&#xff08;AP&#xff09;会影响混凝土中的水分传递&#xff0c;进而影响其微观结构和体积特性&#xff0c;但对其热力学机制却知之甚少 可文献复现 水泥基材料内部的水分运动会直接改变孔隙…...

OpenClaw技能市场巡礼:百川2-13B支持的十大实用插件

OpenClaw技能市场巡礼&#xff1a;百川2-13B支持的十大实用插件 1. 为什么需要技能市场&#xff1f; 第一次接触OpenClaw时&#xff0c;我被它"本地化AI助手"的定位吸引&#xff0c;但很快发现原生功能有限——它能操控鼠标键盘、读写文件&#xff0c;但具体到&quo…...

手把手教你部署GLM-4v-9B:9B参数多模态模型,单卡就能跑

手把手教你部署GLM-4v-9B&#xff1a;9B参数多模态模型&#xff0c;单卡就能跑 1. GLM-4v-9B模型简介 GLM-4v-9B是智谱AI于2024年开源的多模态大模型&#xff0c;具有以下核心特点&#xff1a; 参数规模&#xff1a;90亿参数&#xff0c;单张24GB显存的显卡即可运行多模态能…...

OpenClaw+GLM-4.7-Flash:自动化测试脚本生成器

OpenClawGLM-4.7-Flash&#xff1a;自动化测试脚本生成器 1. 为什么需要自动化测试脚本生成 作为一名长期奋战在一线的开发者&#xff0c;我深知测试环节的重要性与繁琐程度。每当项目进入测试阶段&#xff0c;编写测试用例和脚本往往要占据整个开发周期的30%-40%时间。更令人头…...

深入解析visualization_msgs::Marker:从基础到实战应用

1. visualization_msgs::Marker是什么&#xff1f; 如果你正在用ROS做机器人开发&#xff0c;肯定遇到过这样的需求&#xff1a;想让机器人在rviz里显示一些自定义的图形&#xff0c;比如路径规划时的参考线、传感器检测到的障碍物轮廓&#xff0c;甚至是简单的文字提示。这时候…...

用Arduino UNO R3和MPU6050搞定平衡小车:从硬件接线到PID参数调试全记录

从零打造Arduino平衡小车&#xff1a;硬件搭建与PID调参实战指南 1. 项目准备与硬件选型 平衡小车作为入门机器人的经典项目&#xff0c;融合了传感器技术、控制算法和机电一体化设计。在开始动手前&#xff0c;我们需要准备以下核心组件&#xff1a; 核心硬件清单&#xff1a;…...

C++协程(C++20)原理剖析:co_await的实现机制

C20引入的协程机制为异步编程带来了革命性变化&#xff0c;其中co_await作为核心操作符&#xff0c;其实现机制值得深入探讨。本文将剖析co_await背后的魔法&#xff0c;揭示协程如何通过挂起与恢复实现高效异步。 协程三要素解析 协程由promise对象、协程句柄和协程状态三部…...

你的Matlab三维柱状图为什么不好看?可能是忽略了这3个细节:坐标轴、网格线与字体搭配

你的Matlab三维柱状图为什么不够高级&#xff1f;3个被低估的设计细节解析 科研图表不仅是数据的载体&#xff0c;更是研究者专业素养的视觉名片。当同行评审翻开论文时&#xff0c;一张配色考究、细节精致的图表往往能在几秒钟内建立可信度——这正是许多Matlab用户使用bar3绘…...