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

[C++ 网络协议] 多播与广播

目录

1. 多播

1.1 多播的使用情形

1.2 多播的原理

1.3 如何实现多播

1.4 多播的代码实现

2. 广播

2.1 广播与多播的区别

2.2 广播的分类

2.3 实现广播


1. 多播

1.1 多播的使用情形

        考虑一种情形,你要向10000名用户发送数据,此时如果用TCP提供服务,则需要维护10000个套接字连接,如果用UDP提供服务,则也需要进行10000次数据传输。像这样,在这总情况下,就可以使用多播技术来解决问题。所以一般多播常用于多媒体数据的实时传输

1.2 多播的原理

        多播是基于UDP协议传输的。但又与UDP有一些不同,不同之处在于,UDP数据传输是以单一目标进行的,而多播则会将数据同时传递到加入(注册)多播组的大量主机。

        其中,多播组是一种D类IP地址(224.0.0.0~239.255.255.255),加入多播组,可以理解为在D类IP地址中,我希望接收发往目标239.255.255.255的多播数据。

        其原理如图:

多播数据包的格式与UDP数据包相同,但多播数据包在传输过程中时,路由器会复制该多播数据包并传递到多个主机。由此,主机只需要发送一次数据包,多个主机就能接受到,而无需一个数据包发多次。不像UDP或TCP,n个主机要接受数据包,就得传输n次。

1.3 如何实现多播

实现多播需要:

        1.传递数据包的主机需要设置TTL(Time to Live,生存时间),TTL是决定数据包传送距离的主要因素,TTL用整数表示,每经过一个路由器就减1,直到TTL变为0时,数据包就无法再传输,只能销毁。因此TTL的值设置过大会影响网络流量,但过小就无法传递到目标。

        2.接收数据包的主机需要加入多播组

上述两个条件的设置,用套接字可选项来完成。

条件协议层可选项
设置TTLIPPROTO_IPIP_MULTICAST_TTL
加入多播组IPPROTO_IPIP_ADD_MEMBERSHIP

1.4 多播的代码实现

设置TTL:

int time_to_live=64;
setsockopt(senderfd,IPPROTO_IP,IP_MULTICAST_TTL,(void*)&time_to_live,sizeof(time_to_live);

加入多播组:

ip_mreq join_adr;
join_adr.imr_multiaddr=inet_addr("要加入的多播组IP地址");
join_adr.imr_interface=htonl("加入该组的套接字所属主机的IP地址");setsockopt(recvfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,(void*)&join_adr,sizeof(join_adr));
struct ip_mreq
{struct in_addr imr_multiaddr;    //要加入的多播组IP地址struct in_addr imr_interface;    //加入该组套接字所属主机IP
}

其中,imr_interface可以用INADDR_ANY

Sender:

#include<iostream>
#include<cstring>
#include<sys/socket.h>
#include<unistd.h>
#include<arpa/inet.h>int main()
{int senderfd=socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP);if(senderfd==-1){std::cout<<"socket fail!"<<std::endl;}int ttl=64;int res=setsockopt(senderfd,IPPROTO_IP,IP_MULTICAST_TTL,(void*)&ttl,sizeof(ttl));if(res==-1){std::cout<<"setsockopt fail!"<<std::endl;}std::string strIp;std::cout<<"请输入要发往的多播IP地址:";std::cin>>strIp;sockaddr_in senderAddr;senderAddr.sin_family=AF_INET;senderAddr.sin_addr.s_addr=inet_addr(strIp.c_str());senderAddr.sin_port=htons(9130);std::cout<<"请输入你要发送的内容:";char buff[1024];std::cin>>buff;int sendLen;sendto(senderfd,buff,sizeof(buff),0,(sockaddr*)&senderAddr,sizeof(senderAddr));close(senderfd);return 0;
}

Recv:

#include<iostream>
#include<cstring>
#include<sys/socket.h>
#include<unistd.h>
#include<arpa/inet.h>int main()
{int recvSocket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);if (recvSocket == -1){std::cout << "socket fail!" << std::endl;}sockaddr_in recvAddr;recvAddr.sin_family = AF_INET;recvAddr.sin_addr.s_addr = htonl(INADDR_ANY);recvAddr.sin_port = htons(9130);if (-1 == bind(recvSocket, (sockaddr*)&recvAddr, sizeof(recvAddr))){std::cout << "bind fail!" << std::endl;}std::string strIp;std::cout << "请输入要加入的多播IP地址:";std::cin >> strIp;ip_mreq join_adr;join_adr.imr_multiaddr.s_addr = inet_addr(strIp.c_str());join_adr.imr_interface.s_addr = htonl(INADDR_ANY);int res=setsockopt(recvSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void*)&join_adr, sizeof(join_adr));if (res ==-1){std::cout << "setsockopt fail!" << std::endl;}char buff[1024];recvfrom(recvSocket, buff, sizeof(buff), 0, NULL, 0);    //因为此套接字是已连接UDP套接字,所以无需再进行绑定std::cout <<"接收到的多播信息:" << buff << std::endl;close(recvSocket);return 0;
}

运行结果:

Sender:

Recv:

注意:

1.发送方和接收方的端口号要一致

2.在这里接收方要先于发送方运行,因为多播属于广播的范畴,如果接收方延后,则会接收不到信息。
3.Windows里设置TTL,需要加上头文件#include<ws2tcpip.h>,因为IP_MULTICAST_TTL声明在这个头文件里。

2. 广播

2.1 广播与多播的区别

广播与多播的唯一区别是,广播只能向同一网络中的主机传输数据,而多播是可以跨越不同网络,只要加入多播组就能接收到数据的。

2.2 广播的分类

广播分为:直接广播、本地广播。

两者之间的差别主要是在于IP地址

        直接广播的IP地址除了网络地址外,其余主机地址全部设置为1,。例如,希望向网络地址为192.12.32中的所有主机传输数据,则可以向192.12.32.255传输。换言之,直接广播就是可以向特定区域内所有主机传输数据。

         本地广播的IP地址限定为255.255.255.255。例如,位于192.32.24网络中的主机向255.255.255.255传递数据时,数据将传递到这个网路中的所有主机上。换言之,本地广播就是只能向本地网络区域内所有主机传输数据。

2.3 实现广播

广播的实现需要:

协议层套接字可选项
SOL_SOCKETSO_BROADCAST0【关闭】/1【开启】
int bcast=1;
setsockopt(send_sock,SOL_SOCKET,SO_BROADCAST,(void*)&bcast,sizeof(bcast));

广播的代码实现和多播没有什么区别,只需要把上述代码里套接字可选项改为SO_BROADCAST即可,然后在运行时,输入指定的IP地址(直接广播输入:xxx.xxx.xxx.255,本地广播输入:255.255.255.255)即可。

相关文章:

[C++ 网络协议] 多播与广播

目录 1. 多播 1.1 多播的使用情形 1.2 多播的原理 1.3 如何实现多播 1.4 多播的代码实现 2. 广播 2.1 广播与多播的区别 2.2 广播的分类 2.3 实现广播 1. 多播 1.1 多播的使用情形 考虑一种情形&#xff0c;你要向10000名用户发送数据&#xff0c;此时如果用TCP提供服…...

IOS17正式版今日发布

北京时间9月19日凌晨&#xff0c;苹果公司正式向全球用户推送了期待已久的iOS 17正式版。此次更新为iPhone带来了多项激动人心的功能&#xff0c;包括对“电话”、“信息”、FaceTime通话的重大更新&#xff0c;“待机显示”以及音乐、小组件、Safari浏览器的升级等。 据了解&…...

2560. 打家劫舍 IV

沿街有一排连续的房屋。每间房屋内都藏有一定的现金。现在有一位小偷计划从这些房屋中窃取现金。 由于相邻的房屋装有相互连通的防盗系统&#xff0c;所以小偷 不会窃取相邻的房屋 。 小偷的 窃取能力 定义为他在窃取过程中能从单间房屋中窃取的 最大金额 。 给你一个整数数…...

java web中部署log4j.xml

标题&#xff1a;Java Web中部署log4j.xml 目录&#xff1a; 1. 介绍 2. 配置log4j.xml文件 3. 配置web.xml文件 4. 配置Spring框架 5. 配置Spring Bean 6. 总结 ## 1. 介绍 在Java Web开发中&#xff0c;日志记录是非常重要的一部分。log4j是一个常用的Java日志记录框架&am…...

【张兔兔送书第一期:考研必备书单】

考研书单必备 《数据结构与算法分析》《计算机网络&#xff1a;自顶向下方法》《现代操作系统》《深入理解计算机系统》《概率论基础教程&#xff08;原书第10版》《线性代数&#xff08;原书第10版&#xff09;》《线性代数及其应用》赠书活动 八九月的朋友圈刮起了一股晒通知…...

基于Spring Boot+ Vue的健身房管理系统与实现

小熊学Java全能学面试指南&#xff1a;https://javaxiaobear.cn 摘要 随着健身行业的快速发展&#xff0c;健身房管理系统成为了提高管理效率和用户体验的重要工具。本论文旨在设计与实现一种基于前后端分离的健身房管理系统&#xff0c;通过前后端分离的架构模式&#xff0c;…...

ThreadLocal线程局部变量

1.原理 ThreadLocal是用来保存当前线程数据的&#xff0c;每一个线程的内部都有一个ThreadLocalMap&#xff0c;当前这个map中存储了以当前ThreadLocal作键&#xff0c;具体的数据作值的一个个Entry对象。 为什么非得以ThreadLocal对象作键呢&#xff1f;因为一个线程可能使用了…...

C++ Primer (第五版)第一章习题部分答案

在我自学C过程中&#xff0c;我选择了CPrimer这本书&#xff0c;并对部分代码习题进行了求解以及运行结果。接下来几个月我将为大家定时按章节更新习题答案与运行结果: 目录 1.9编写程序,使用while循环将50到100的整数相加 1.10 除了运算符将运算对象的值增加1之外,还有一个…...

Python与GUI集成:零基础也能开发国际象棋游戏

引言&#xff1a; 国际象棋&#xff0c;作为世界上最受欢迎的棋类游戏之一&#xff0c;拥有丰富的策略和深度。但是&#xff0c;你知道自己可以使用Python来创建一个简单的国际象棋游戏并为其添加图形用户界面&#xff08;GUI&#xff09;吗&#xff1f;在本教程中&#xff0c…...

SaaS软件能保证数据安全吗?

SaaS软件能保证数据安全吗&#xff1f; 本文将要尝试从各个方面尽可能客观的去阐述这个问题&#xff0c;而不是简单自嗨式的说简道云平台如何保障数据安全。 建议先收藏起来慢慢品&#xff01; 01 SaaS安全到底是什么&#xff1f;——定义解读 本文所用SaaS平台>>>…...

方案:基于AI烟火识别与视频技术的秸秆焚烧智能化监控预警方案

一、方案背景 为严控秸秆露天焚烧&#xff0c;改善环境空气质量&#xff0c;各省相继发布秸秆禁烧工作内容。以安徽省为例&#xff0c;大气污染防治联席会议下发了该省2020年秸秆禁烧工作部署通知。2020年起&#xff0c;气象局将对全省秸秆焚烧火点实施卫星全年全时段监测&…...

phantomjs插件---实现通过链接生成网页截图

Phantomjs | PhantomJS 配置要求 windows下&#xff0c;安装完成phantomJS 设置phantomjs环境变量【也可直接使用phantomjs目录下的执行文件】 直接通过访问php文件执行/通过cmd命令行执行【phantomjs phantom_script.js】 linux下,安装完成phantomJS 设置phantomjs环境变量 直…...

SpringBoot分页实现查询数据

1.原生查询 1.1创建分页查询实体类 package com.itheima.pojo;import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;import java.util.List;//分页查询结果封装类 Data NoArgsConstructor AllArgsConstructor public class PageBean {pr…...

Jetson Xavier NX 与飞控(Pixhawk 4 Mini)实现串口通信

一、飞控端配置 首先对 Pixhawk 4 Mini 烧录固件参考 Kakute H7 刷写 px4 固件_想要个小姑娘的博客-CSDN博客 烧录完成后打开 QGroundControl&#xff0c;进入参数设置并搜索 MAV&#xff0c;如下所示 然后修改 MAV_1_CONFIG&#xff0c;修改为自己想要连接机载电脑&#xf…...

为什么2022年秋招嵌入式开发岗位薪资大涨?

今天看到一个网友讨论的问题&#xff0c;其实这个问题也很简答。从嵌入式本身优势来说&#xff0c;首先是因为该行业人才人才需求大&#xff0c;据权威统计机构统计在所有软件开发类人才的需求中&#xff0c;对嵌入式工程师的需求达到全部需求量的60%~80%&#xff0c;并且每年以…...

在HTML里,attribute和property有什么区别?

在HTML中&#xff0c;attribute 和 property 之间的区别是一个常见但容易混淆的概念。它们都与HTML元素有关&#xff0c;但它们在功能、用途和行为上有所不同。以下是它们之间的主要区别&#xff1a; 定义和来源: Attribute: 它们是在HTML标记中定义的&#xff0c;通常用于提供…...

机器学习入门与实践:从原理到代码

&#x1f482; 个人网站:【工具大全】【游戏大全】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 寻找学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 在本文中&#xff0c;我…...

SpringCloud在idea中一键启动项目

1、如下图文件中加上&#xff1a; <component name"RunDashboard"><option name"configurationTypes"><set><option value"SpringBootApplicationConfigurationType" /></set></option></component>…...

VB过程的递归调用,辗转相除法求最大公约数

VB过程的递归调用&#xff0c;辗转相除法求最大公约数 过程的递归调用&#xff0c;辗转相除法求最大公约数 Private Function gys(ByVal m%, ByVal n%) As IntegerDim r%r m Mod n m大或者n大都无所谓&#xff0c;这个不影响计算&#xff0c;由于辗转相除法的算法&#xff0c…...

OpenCV(三十九):积分图像

1.积分图像介绍 积分图像中的每个像素表示了原始图像中对应位置及其左上方矩形区域内像素值的总和。如图&#xff0c;p0表示原始图像蓝色区域内像素值的总和。 倾斜求和&#xff08;Skewed Sum&#xff09;是积分图像的一种扩展形式&#xff0c;用于计算图像区域内的像素和&…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计&#xff1a;let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性&#xff0c;这种设计体现了语言的核心哲学。以下是深度解析&#xff1a; 1.1 设计理念剖析 安全优先原则&#xff1a;默认不可变强制开发者明确声明意图 let x 5; …...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

条件运算符

C中的三目运算符&#xff08;也称条件运算符&#xff0c;英文&#xff1a;ternary operator&#xff09;是一种简洁的条件选择语句&#xff0c;语法如下&#xff1a; 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true&#xff0c;则整个表达式的结果为“表达式1”…...

Neo4j 集群管理:原理、技术与最佳实践深度解析

Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

零基础设计模式——行为型模式 - 责任链模式

第四部分&#xff1a;行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习&#xff01;行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想&#xff1a;使多个对象都有机会处…...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...