广播和组播

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.mfbz.cn/a/228229.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

无需繁琐编程 开启高效数据分析之旅!

不学编程做R统计分析&#xff1a;图形界面R Commander官方手册 R Commander是 R 的图形用户界面&#xff0c;不需要键入命令就可通过熟悉的菜单和对话框来访问 R 统计软件。 R 和 R Commander 均可免费安装于所有常见的操作系统——Windows、Mac OS X 和 Linux/UNIX。 本书作…

DataGrip常见问题

查询语句结果没有输出在output中 进行如下配置 配置后查询结果输出在output中 左侧数据库链接信息导航栏被隐藏 以上导航栏被隐藏&#xff0c;按下图操作调出

自定义TypeHandler 将mysql返回的逗号分隔的String转换到List

sql执行如下&#xff1a; 这里我定义的接受类&#xff1a; 但是这里报了错JSON parse error: Cannot deserialize value of type java.util.ArrayList<java.lang.String>from Object value (token JsonToken.START_OBJECT); nested exception is com.fasterxml.jackson…

第六届“强网”拟态防御国际精英挑战赛 持续引领技术发展新潮流

12月6日&#xff0c;第六届“强网”拟态防御国际精英挑战赛在南京紫金山实验室盛大开幕&#xff0c;来自全球的40支顶尖战队开启了连续72小时的高强度对决。 本届挑战赛由江苏省委网信办指导&#xff0c;南京市委网信办、紫金山实验室、中国通信学会主办&#xff0c;是第三届网…

高精度加法,减法,乘法,除法(下)(C语言)

前言 上一篇博客我们分享了高精度加法&#xff0c;减法,这一期我将为大家讲解高精度乘法和高精度除法。那让我们开始吧&#xff01; 对加法和减法感兴趣的话就点我 文章目录 1&#xff0c;乘法2&#xff0c;除法3&#xff0c;尾声 1&#xff0c;乘法 让我们想想我们平时做数学…

使用高防IP防护有哪些优势

高防IP是针对互联网服务器在遭受大流量的DDoS攻击后导致服务不可用的情况下&#xff0c;推出的付费增值服务&#xff0c;用户可以通过配置高防IP&#xff0c;将攻击流量引流到高防IP&#xff0c;确保源站的稳定可靠。高防IP相当于搭建完转发的服务器。 高防IP有两种接入方式&a…

vue如何解决el-select下拉框显示ID不显示label问题

<template><el-select v-model"searchObj.saleAreaId" change"searchClick" placeholder"请选择" class"inpt1" clearablesize"small"><el-option v-for"item in saleAreaList" :key"item.id…

机器学习实战:预测波士顿房价

前言&#xff1a; Hello大家好&#xff0c;我是Dream。 今天来学习一下机器学习中一个非常经典的案例&#xff1a;预测波士顿房价&#xff0c;在此过程中也会补充很多重要的知识点&#xff0c;欢迎大家一起前来探讨学习~ 一、导入数据 在这个项目中&#xff0c;我们利用马萨诸…

uView的使用

下载好uView后&#xff0c;我们可以快速的去使用 JS中工具库的使用 例如&#xff1a;time 时间格式 | uView - 多平台快速开发的UI框架 - uni-app UI框架 我们可以快速的使用内置函数&#xff0c;例如以下时间戳&#xff1a; http请求 但是我们需要注意的是&#xff0c;需要…

Linux下的同步命令代码编写

1.设置静态IP vi /etc/syscnfig/network-scripts/ifcfg-eth1 2.设置主机名 hostnamectl --static set-hostname 主机名 如&#xff1a;hostnamectl --static set-hostname hadoop001 3.配置IP与主机名映射 vi /etc/hosts 4.关闭防火墙 systemctl stop firewalld systemctl…

Nucleo-F103RB-简介

Nucleo-F103RB-简介 1. 前言2. 概述3. 微控制器特性4. Nucleo 功能5. 电路板引脚排列6. 支持的测试板矩阵7. ST MCU板8. ST 扩展板1. 前言 经济实惠且灵活的平台,可简化使用STM32F103RBT6微控制器的原型设计。 2. 概述 STM32 Nucleo开发板为用户提供了一种经济实惠且灵活的…

创新驱动发展丨暴雨信息受邀参加广东省公路工程学术交流会

为加强公路交通工程领域技术交流&#xff0c;结合公路交通工程技术发展和行业热点问题&#xff0c;广东省公路学会联合中国公路学会交通工程与信息化分会举办公路工程学术交流会。学术交流会以“交通工程智能化新技术应用及高速公路改扩建机电工程经验交流”为主题&#xff0c;…

【开源】基于Vue+SpringBoot的河南软件客服系统

文末获取源码&#xff0c;项目编号&#xff1a; S 067 。 \color{red}{文末获取源码&#xff0c;项目编号&#xff1a;S067。} 文末获取源码&#xff0c;项目编号&#xff1a;S067。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统管理人员2.2 业务操作人员 三、…

11.Java安卓程序设计-基于SSM框架的Android平台健康管理系统的设计与实现

摘要 随着人们生活水平的提高和健康意识的增强&#xff0c;健康管理系统在日常生活中扮演着越来越重要的角色。本研究旨在设计并实现一款基于SSM框架的Android平台健康管理系统&#xff0c;为用户提供全面的健康监测和管理服务。 在需求分析阶段&#xff0c;我们明确了系统的…

Java---线程讲解(二)

文章目录 1. Runnable接口2. 卖票案例3. 同步代码块解决数据安全问题4. 同步方法解决数据安全问题5. 线程安全的类6. Lock锁 1. Runnable接口 1. 创建线程的另一种方法是声明一个实现Runnable接口的类&#xff0c;之后重写run()方法&#xff0c;然后可以分配类的实例&#xff0…

vmware安装centos7总结

vmware安装centos7总结 文章目录 vmware安装centos7总结一、配置网络&#xff08;桥接模式&#xff09;二、配置yum源&#xff08;连网配置&#xff09;三、可视化界面四、安装Docker五、安装DockerUI 一、配置网络&#xff08;桥接模式&#xff09; 网络连接模式选择桥接模式…

打包 抖音直播云游戏

抖音直播云游戏 oaid资源中的bcpkix-jdk15to18-1.68.jar与抖音云游戏的资源冲突。 其实资源名称是一样的&#xff0c;拷贝时资源名称有变化。 为解决此问题&#xff0c;需要规范化文件的资源名称&#xff0c;将.置为_ Error: Command failed: cmd /c echo off && Chc…

Java实现Socket聊天室

一、网络编程是什么&#xff1f; 在网络通信协议下&#xff0c;不同计算机上运行的程序&#xff0c;进行数据传输。 应用场景&#xff1a;即时通讯、网游对战、金融证券、国际贸易、邮件、等等。 不管是什么场景&#xff0c;都是计算机与计算机之间通过网络进行数据传输。 …

Docker网络原理及Cgroup硬件资源占用控制

docker的网络模式 获取容器的进程号 docker inspect -f {{.State.Pid}} 容器id/容器名 docker初始状态下有三种默认的网络模式 &#xff0c;bridg&#xff08;桥接&#xff09;&#xff0c;host&#xff08;主机&#xff09;&#xff0c;none&#xff08;无网络设置&#xff…

Linux C语言 39-进程间通信IPC之管道

Linux C语言 39-进程间通信IPC之管道 本节关键字&#xff1a;C语言 进程间通信 管道 FIFO 相关库函数&#xff1a;pipe、mkfifo、mknod、write、read 什么是管道&#xff1f; 管道通常指“无名管道”&#xff0c;是Unix系统中最古老的IPC通信方式。 管道的分类 管道&#…
最新文章