广播和组播

news2024/11/17 5:42:11

1. 广播

1.1 知识点

INADDR_ANY代表本机所有地址 常用方法当你将套接字绑定到INADDR_ANY,它会监听所有可用的网络接口,这意味着它将接受来自所有本地IP地址的传入连接或数据包

1.1.1 广播的流程

广播发送端: ----> 添加广播属性

1、建立套接字

2、设置该套接字允许进行广播(将广播属性添加进去)

3、填充服务端的结构体广播网络地址

4、将数据发送到广播地址中(sendto)

5、关闭

接收端(服务器): ----> 绑定所有主机(INADDR_ANY)

1、建立套接字

2设置该套接字允许进行广播(将广播属性添加进去)

3、填充服务端的结构体, 将套接字与广播信息结构体绑定(广播地址和端口号(端口号和广播端口一致))

4、创建结构体存放发送端IP和端口

5、接收数据 recvfrom( )

6、关闭

1.1.2 函数

接口声明:setsockopt() 函数:用于设置套接字选项,以启用广播功能。

参数

sockfd:套接字文件描述符。

level:指定选项所属的协议层,通常是 SOL_SOCKET。

optname:指定要设置的选项,通常是 SO_BROADCAST,表示启用广播。

optval:指向一个整数变量的指针,通常设置为 1 表示启用广播。

optlen:optval 变量的大小

返回值:

setsockopt() 函数的返回值通常是整数类型的,表示函数调用的成功与否。在成功设置套接字选项时,setsockopt() 返回0,表示操作成功。如果出现错误,则返回-1,并且可以使用 errno 全局变量来确定导致错误的具体原因。

1.2 广播发送消息

发送端broadcast_s.c

#include <sys/types.h>        
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
//广播发送消息
//发送端
int main()
{
    //1. 创建udp套接字
	int sock_fd = socket(AF_INET,SOCK_DGRAM,0);

    //2. 用于设置为允许发送广播权限(套接字默认关闭广播属性),以启用广播功能。
    int optval = 1;
    socklen_t optval_len = sizeof(optval);//计算长度
    int ret = setsockopt(sock_fd,SOL_SOCKET,SO_BROADCAST,&optval,optval_len);//SOL_SOCKET协议,SO_BROADCAST开启广播
    if(-1==ret){
        perror("开启广播失败");
        return -1;
    }


    //这些没必要写,写了也没事
    // local_addr.sin_family = AF_INET;//网际协议
    // local_addr.sin_port = htons(8888);//设置端口 //htons功能是转为主机字节序
    // local_addr.sin_addr.s_addr = INADDR_ANY;//设置ip  INADDR_ANY自动获取本机ip
    // socklen_t local_addr_len = sizeof(local_addr);//计算本机网络地址大小
    // //绑定
    // bind(sock_fd,(struct sockaddr*)&local_addr,local_addr_len);

    //3. 初始化广播地址
    struct sockaddr_in broadcast_addr;

    broadcast_addr.sin_family = AF_INET;//网际协议
    broadcast_addr.sin_port = htons(10000);//设置端口 //htons功能是转为主机字节序
    broadcast_addr.sin_addr.s_addr = inet_addr("192.168.124.255");//设置ip  
    socklen_t broadcast_addr_len = sizeof(broadcast_addr);//计算广播网络地址大小

    char sbuf[128];
    while(1){
        memset(sbuf,0,sizeof(sbuf));
        fgets(sbuf,sizeof(sbuf),stdin);
        //4. 广播发送
        sendto(sock_fd,sbuf,sizeof(sbuf),0,(struct sockaddr*)&broadcast_addr,broadcast_addr_len);
    }

    return 0;
}

接收端broadcast_r.c

#include <sys/types.h>        
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
//广播发送消息
//接收端
int main()
{
    //1. 创建udp套接字
	int sock_fd = socket(AF_INET,SOCK_DGRAM,0);
    if(sock_fd ==-1)
	{
		perror("open sock failed");
		return -1;
	}

    //2. 用于设置套接字选项,以启用广播功能。
    int optval = 1;
    socklen_t optval_len = sizeof(optval);//计算长度
    int ret = setsockopt(sock_fd,SOL_SOCKET,SO_BROADCAST,&optval,optval_len);//SOL_SOCKET协议,SO_BROADCAST开启广播
    if(-1==ret){
        perror("开启广播失败");
        return -1;
    }

    //3. 初始化广播地址和绑定套接字
    struct sockaddr_in local_addr;
    local_addr.sin_family = AF_INET;//网际协议
    //接收端端口必须和广播端口一致
    local_addr.sin_port = htons(10000);//设置端口 //htons功能是转为主机字节序
    //INADDR_ANY代表本机所有地址 常用方法当你将套接字绑定到INADDR_ANY,它会监听所有可用的网络接口
    //,这意味着它将接受来自所有本地IP地址的传入连接或数据包
    local_addr.sin_addr.s_addr = INADDR_ANY;//设置ip  
    socklen_t local_addr_len = sizeof(local_addr);//计算本机网络地址大小
    //绑定
    bind(sock_fd,(struct sockaddr*)&local_addr,local_addr_len);

    //4. 定义结构体接收网络地址信息
    struct sockaddr_in broadcast_addr;
    socklen_t broadcast_addr_len = sizeof(broadcast_addr);//计算本机网络地址大小

    
    char rbuf[128];
    while(1){
        memset(rbuf,0,sizeof(rbuf));
        //5. 接收消息
        recvfrom(sock_fd,rbuf,sizeof(rbuf),0,(struct sockaddr*)&broadcast_addr,&broadcast_addr_len);

        //将是一个用于将 IPv4 地址从二进制形式转换为点分十进制字符串形式的C库函数。
		char *ip = inet_ntoa(broadcast_addr.sin_addr);//ip
		unsigned short port = ntohs(broadcast_addr.sin_port);//端口号

        printf("%s %u接收广播的消息为:%s\n",ip,port,rbuf);
    
    }

    return 0;
}

2. 组播

2.1 知识点

2.1.1 组播特点

1)需要给组播设置IP地址,该IP必须是D类地址

2)只有UDP才能设置组播

3) IP地址分类 IP地址 = 网络号 + 主机号

网络号:指的是不同的网络

主机号:指的是同一个网段下用来识别不同的主机。

那也就是说,主机号所占的位数越多,在该网段下的主机 数越多

A类地址 :保留给政府机构使用

A类IP地址就由1字节的网络地址和3字节主机地址组成,网络地址的最高位必须 是“0”

A类地址范围 1.0.0.1 - 126.255.255.254

B类地址 :分配给中等规模的公司

B类IP地址就由2字节的网络地址和2字节主机地址组成,网络地址的最高位必须 是“10”

B类地址范围 128.0.0.1 - 191.255.255.254

C类地址 :分配给任何需要的人

C类IP地址就由3字节的网络地址和1字节主机地址组成,网络地址的最高位必须 是“110” 13 C类地址范围 192.0.0.1 - 223.255.255.254 

D类地址 :用于组播

D类地址范围 224.0.0.1 - 239.255.255.254 

E类地址 :用于实验

E类地址范围 240.0.0.1 - 255.255.255.254

2.1.2 组播通信的过程

 UDP组播发送端

1、建立套接字()

2、设置组播地址等属性

3、发送数据

4、关闭

UDP组播接收端

1、建立套接字

2定义组播结构体,设置组播ip(初始化 组播结构体)

3、加入组播属性(也就是设置这个套接字 可以接收组播信息)

4、绑定IP地址和端口号

5、创建结构体存放IP和端口

6、接收数据

7、关闭

组播结构体

struct ip_mreq

{

struct in_addr imr_multiaddr; //组播地址

struct in_addr imr_interface;       //本机地址

}

struct in_addr imr_multiaddr

{

s_addr;//组播地址

}

struct in_addr imr_interface

{

s_addr;//本机地址

}

2.2 组播通信

发送端zubo_s.c

#include <sys/types.h>        
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
//组播发送消息
//发送端
int main()
{
    //1.创建udp套接字
	int sock_fd = socket(AF_INET,SOCK_DGRAM,0);
    if(sock_fd ==-1)
	{
		perror("open sock failed");
		return -1;
	}

    //2.初始化组播地址
    struct sockaddr_in send_addr;
    send_addr.sin_family = AF_INET;//网际协议
    //接收端端口必须和组播端口一致
    send_addr.sin_port = htons(10002);//设置端口 
    send_addr.sin_addr.s_addr = inet_addr("224.0.0.1");//设置组播ip 

    socklen_t send_addr_len = sizeof(send_addr);//计算本机网络地址大小

    char sbuf[128];
    while(1){

        memset(sbuf,0,sizeof(sbuf));
        fgets(sbuf,sizeof(sbuf),stdin);
        //3. 发送消息
        sendto(sock_fd,sbuf,sizeof(sbuf),0,(struct sockaddr*)&send_addr,send_addr_len);

    }
    //4. 关闭
    close(sock_fd);

    return 0;
}

接收端zubo_r.c

#include <sys/types.h>        
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
//组播发送消息
//接收端
int main()
{
    //1.创建udp套接字
	int sock_fd = socket(AF_INET,SOCK_DGRAM,0);
    if(sock_fd ==-1)
	{
		perror("open sock failed");
		return -1;
	}

    //2.定义组播结构体,设置组播ip(初始化 组播结构体)
    struct ip_mreq m;
    m.imr_multiaddr.s_addr = inet_addr("224.0.0.1");//组播地址
    m.imr_interface.s_addr = INADDR_ANY;//主机地址(需要添加到组的ip)
    socklen_t m_len = sizeof(m);

    //3.加入组播属性(也就是设置这个套接字 可以接收组播信息)
    setsockopt(sock_fd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&m,m_len);

    //4.初始化本地地址和绑定套接字
    struct sockaddr_in local_addr;
    local_addr.sin_family = AF_INET;//网际协议
    local_addr.sin_port = htons(10002);//设置端口 //htons功能是转为主机字节序
    local_addr.sin_addr.s_addr = INADDR_ANY;//设置ip  

    socklen_t local_addr_len = sizeof(local_addr);//计算本机网络地址大小
    //绑定
    bind(sock_fd,(struct sockaddr*)&local_addr,local_addr_len);

    //5. 定义结构体接收网络地址信息
    struct sockaddr_in recv_addr;
    socklen_t recv_addr_len = sizeof(recv_addr);//计算本机网络地址大小

    char rbuf[128];
    while(1){

        memset(rbuf,0,sizeof(rbuf));
        //6. 接收消息
        recvfrom(sock_fd,rbuf,sizeof(rbuf),0,(struct sockaddr*)&recv_addr,&recv_addr_len);

        //将是一个用于将 IPv4 地址从二进制形式转换为点分十进制字符串形式的C库函数。
		char *ip = inet_ntoa(recv_addr.sin_addr);//ip
		unsigned short port = ntohs(recv_addr.sin_port);//端口号

        printf("接收%s %u的组播消息为:%s\n",ip,port,rbuf);
    
    }
    //7. 关闭
    close(sock_fd);

    return 0;
}

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

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

相关文章

JAVA后端自学技能实操合集

JAVA后端自学技能实操 内容将会持续更新中,有需要添加什么内容可以再评论区留言,大家一起学习FastDFS使用docker安装FastDFS(linux)集成到springboot项目中 内容将会持续更新中,有需要添加什么内容可以再评论区留言,大家一起学习 FastDFS 组名&#xff1a;文件上传后所在的 st…

MySQL中是如何insert数据的

正常insert数据&#xff0c;MySQL并不会显式加锁&#xff0c;而是通过聚簇索引的trx_id索引作为隐式锁来保护记录的。比如两个事务对一个非唯一的索引情况添加&#xff0c;会造成幻读 但在某些特殊情况下&#xff0c;隐式锁会转变为显式锁&#xff1a; 记录之间有间隙锁inser…

Qt使用Cryptopp生成HMAC-MD5

近期项目中HTTPS通讯中&#xff0c;token需要使用HMAC-MD5算法生成&#xff0c;往上找了一些资料后&#xff0c;仍不能满足自身需求&#xff0c;故次一记。 前期准备&#xff1a; ①下载Cryptopp库&#xff08;我下载的是8.8.0 Release版本&#xff09;&#xff1a;Crypto Li…

基础课19——知识图谱问答引擎

1.概念 知识图谱是一种结构化的知识表示方式&#xff0c;将实体、属性和关系以图形的形式进行表达和组织。它通过对知识进行结构化建模&#xff0c;将不同实体之间的关系进行编码&#xff0c;形成一个图结构的知识网络。知识图谱的目标是将人类的知识整合到一个统一的框架中&a…

Segment Anything--SAM框架(二)

文章目录 prologuepaper && codeImage encoderPrompt encoderLightweight mask decoderMaking the model ambiguity-aware prologue 没什么事&#xff0c;写一写SAM的paper中关于模型框架的部分和实际代码部分。 paper && code SAM有三个组件&#xff0c;如图…

图数据库知识点9 | 大数据框架与图数据架构异同

开门见山&#xff0c;直奔主题&#xff0c;接续前面的知识点&#xff1a; 【图数据库知识点1|图数据库与关系型数据库的区别&#xff1f;】 【图数据库知识点2 | 图思维方式】 【图数据库知识点3 | 图数据库解决了什么问题&#xff1f;】 【图数据库知识点4 | 图计算与图数…

TypeScript枚举类型、类型断言

一. 概念 TypeScript中的枚举是一种数据类型&#xff0c;它是一组具有预定义名称的有限值的集合。枚举类型可以使代码更加可读、可维护和易于理解。 类似对象&#xff0c;枚举是将一组无序但极度相关数组集合在一起声明存储。 二. 枚举特性 1. 内部进行了双向赋值 enum Numb…

奕碳科技亮相COP28:展现中国智慧,引领全球碳减排新篇章

11月30日,联合国气候变化框架公约第28次缔约方大会 (COP28) 在阿联酋迪拜开幕。COP28是全球气候治理的重要盛会&#xff0c;汇聚了世界各国领导人、企业界和科学界代表&#xff0c;共同探讨和制定应对全球气候变化的策略与行动计划。在这样的背景下&#xff0c;企业群体的积极参…

力扣题:字符的统计-12.7

力扣题-12.7 [力扣刷题攻略] Re&#xff1a;从零开始的力扣刷题生活 力扣题1&#xff1a;467. 环绕字符串中唯一的子字符串 解题思想&#xff1a;记录下以字母s[i]结尾的最大的字串个数&#xff0c;然后统计a-z每个字母结尾的最大字串的个数进行i相加 class Solution(object…

「Verilog学习笔记」同步FIFO

专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点&#xff0c;刷题网站用的是牛客网 timescale 1ns/1ns /**********************************RAM************************************/ module dual_port_RAM #(parameter DEPTH 16,parameter WIDTH 8)(in…

Anaconda建虚拟环境并在jupyter中打开

1.假设要用yaml格式创建虚拟环境 从开始里打开anaconda powersheel 输入以下 conda env create -f environment.yaml conda activate env_name activate以下虚拟环境 修改名称 如果不用yaml也可以用 conda create --name my_first_env python3.6 这个来指定 2.(base)变(…

海思3516DV500下的目标识别算法运行评估,包含yolov7,yolov8

目前在3516DV500下&#xff0c;自己训练的模型的评估实测结果。根据实际模型会有些许差异。 涉及到技术细节的部分因为商业用途&#xff0c;有部分省略。如需相关技术服务项目合作可私信联系。 我司推出的目标识别跟踪模块&#xff0c;支持热红外、可见光主流多光谱视频输入与目…

LCR 090. 打家劫舍 II(leetcode)动态规划

文章目录 前言一、题目分析二、算法原理1.状态表示2.状态转移方程3.初始化4.填表顺序5.返回值是什么 三、代码实现总结 前言 在本文章中&#xff0c;我们将要详细介绍一下LeetcodeLCR 090. 打家劫舍 II。采用动态规划解决&#xff0c;这是一道经典的多状态dp问题 一、题目分析…

微前端 -- wujie 预加载和原理 无界传参

目录 wujie 预加载和原理 原理解析 MessageChannel 无界传参 1.全局变量 2.Props 3.event bus wujie 预加载和原理 提前把无界实例创建好 runPreload 赋值给sandbox.preload 预先加载好 startApp 判断是否有preload 需要从wujie的实例导出preloadApp,参数跟startApp 一…

Grad-CAM原理

这篇是我对哔哩哔哩up主 霹雳吧啦Wz 的视频的文字版学习笔记 感谢他对知识的分享 只要大家一提到深度学习 缺乏一定的解释性 比如说在我们之前讲的分类网络当中 网络它为什么要这么预测 它针对每个类别所关注的点在哪里呢 在great cam这篇论文当中呢 就完美的解决了在cam这篇论…

《文存阅刊》期刊发表简介

《文存阅刊》以“深研文化创新&#xff0c;崇尚科学真理&#xff0c;坚持双百方针&#xff0c;打造学术精品”为办刊宗旨&#xff0c;涵盖艺术、文学、社科等多项内容&#xff0c;适应了文化市场需求&#xff0c;很好的回应了广大文化理论工作者的关切&#xff0c;为下一步打造…

QMenu风格设计qss+阴影

Qt的菜单经常在软件开发中用到&#xff0c;默认的菜单效果都不符合设计师的要求&#xff0c;本篇介绍QMenu菜单的风格设计&#xff0c;包括样式表和阴影。 1.QMenu样式表的设计 首先看一个默认的菜单 void QGraphicsDropShadowEffectDemo::slotShowDialog() {qDebug() <&l…

机器学习第15天:GBDT模型

☁️主页 Nowl &#x1f525;专栏《机器学习实战》 《机器学习》 &#x1f4d1;君子坐而论道&#xff0c;少年起而行之 ​​ 文章目录 GBDT模型介绍 Boosting 残差 GBDT的缺点 python代码实现 代码 模型参数解释 结语 GBDT模型介绍 GBDT&#xff08;Gradient Boos…

pytest +uiautomator2+weditor app自动化从零开始

目录结构1.0 把设备连接单独移出去了 模块操作代码&#xff0c;有一些流程操作和断言方法 from devices import dv from time import sleep import random from tool.jt import capture_screenshotdef initialization(func):def wrapper():sleep(1)dv.app_stop(com.visteon.…

Linux学习笔记3 xshell(lnmp)

xshell能连接虚拟机的前提是真机能够ping通虚拟机网址 装OpenSSL依赖文件 [rootlocalhost nginx-1.12.2]# yum -y install openssl pcre-devel 依赖检测[rootlocalhost nginx-1.12.2]# ./configure [rootlocalhost nginx-1.12.2]# yum -y install zlib [rootlocalhost n…