UDP广播

news2024/10/5 8:08:21

1、UDP广播

1.1、广播的概念

广播:由一台主机向该主机所在子网内的所有主机发送数据的方式

例如 :192.168.3.103主机发送广播信息,则192.168.3.1~192.168.3.254所有主机都可以接收到数据

广播只能用UDP或原始IP实现,不能用TCP

1.2、广播的用途

单个服务器与多个客户主机通信时减少分组流通 以下几个协议都用到广播

1、地址解析协议(ARP)

2、动态主机配置协议(DHCP)

3、网络时间协议(NTP)

1.3、广播的特点

  1. 同一子网内的所有主机都必须处理接收到的数据。这意味着当一台主机发送广播信息时,子网内的所有其他主机都将接收并处理该数据,无论它们是否需要该信息。
  2. 由于广播只能通过UDP或原始IP实现,因此UDP数据包会沿着协议栈向上传输,直到到达UDP层。这与TCP不同,TCP数据包在传输过程中会经过更多的协议层处理。
  3. 运行音频、视频等高速率应用时,广播通信可能会带来较大的负载。这是因为所有主机都必须处理接收到的数据,即使它们并不需要这些数据。这可能会导致网络拥塞和性能下降。
  4. 广播通信通常局限于局域网(LAN)内使用。这是因为广播信息会被发送到子网内的所有主机,而不同子网之间的通信通常需要使用其他网络协议,如单播或多播。

1.4、广播地址

{网络ID,主机ID}

网络ID表示由子网掩码中1覆盖的连续位

主机ID表示由子网掩码中0覆盖的连续位

定向广播地址:主机ID全1

1、例:对于192.168.220.0/24,其定向广播地址为192.168.220.255 2、通常路由器不转发该广播

受限广播地址:255.255.255.255

路由器从不转发该广播

2 、广播与单播的对比

单播

 广播

3 、广播流程 

  1. 创建套接字:使用socket()函数创建一个数据报套接字(SOCK_DGRAM),以支持UDP通信。
  2. 设置广播权限:使用setsockopt()函数将套接字设置为允许发送广播数据。这通常需要设置SO_BROADCAST选项。
  3. 发送数据:使用sendto()函数向广播地址发送数据。广播地址是一个特殊的IP地址,用于表示子网内的所有主机。例如,在IPv4中,广播地址通常表示为子网掩码全1的形式。

接收广播数据的步骤如下:

  1. 创建套接字:与发送者一样,使用socket()函数创建一个数据报套接字(SOCK_DGRAM)。
  2. 绑定套接字:使用bind()函数将套接字与一个本地地址和端口号绑定。这将使套接字能够接收发送到该地址和端口的数据。
  3. 接收数据:使用recvfrom()函数接收发送到绑定地址和端口的数据。该函数将返回发送者的信息,包括其IP地址和端口号。

4、套接字选项 

#include <sys/socket.h>

int setsockopt(int socket, int level, int option_name,
               const void *option_value, socklen_t option_len);

功能:设置一个套接字的选项(属性)

参数:
    socket:文件描述符
    level:协议层次
      SOL_SOCKET 套接字层次
      IPPROTO_TCP tcp层次
      IPPROTO_IP IP层次
    option_name:选项的名称
      SO_BROADCAST 允许发送广播数据(SOL_SOCKET层次的)
    option_value:设置的选项的值
    int类型的值,存储的是bool的数据(1和0)
      0 不允许
      1 允许
option_len:option_value的长度

返回值:
    成功:0
    失败:-1

 5、广播示例 

5.1 发送者

//广播发送者代码实现
#include <stdio.h> //printf
#include <stdlib.h> //exit
#include <sys/types.h>
#include <sys/socket.h> //socket
#include <netinet/in.h> //sockaddr_in
#include <arpa/inet.h> //htons inet_addr
#include <unistd.h> //close
#include <string.h>

int main(int argc, char const *argv[])
{
    if(argc < 3)
    {
        fprintf(stderr, "Usage: %s <ip> <port>\n", argv[0]);
        exit(1);
    }

    int sockfd; //文件描述符
    struct sockaddr_in broadcataddr; //服务器网络信息结构体
    socklen_t addrlen = sizeof(broadcataddr);

    //第一步:创建套接字
    if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    {
        perror("fail to socket");
        exit(1);
    }

    //第二步:设置为允许发送广播权限
    int on = 1;
    if(setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0)
    {
        perror("fail to setsockopt");
        exit(1);
    }

    //第三步:填充广播信息结构体
    broadcataddr.sin_family = AF_INET;
    broadcataddr.sin_addr.s_addr = inet_addr(argv[1]); //192.168.3.255 255.255.255.255
    broadcataddr.sin_port = htons(atoi(argv[2]));

    //第四步:进行通信
    char buf[128] = "";
    while(1)
    {
        fgets(buf, sizeof(buf), stdin);
        buf[strlen(buf) - 1] = '\0';

        if(sendto(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&broadcataddr, addrlen) < 0)
        {
            perror("fail to sendto");
            exit(1);
        }
    }

    return 0;
}

5.2 接收者

#include <stdio.h> //printf
#include <stdlib.h> //exit
#include <sys/types.h>
#include <sys/socket.h> //socket
#include <netinet/in.h> //sockaddr_in
#include <arpa/inet.h> //htons inet_addr
#include <unistd.h> //close
#include <string.h>

int main(int argc, char const *argv[])
{
    if(argc < 3)
    {
        fprintf(stderr, "Usage: %s <ip> <port>\n", argv[0]);
        exit(1);
    }

    int sockfd; //文件描述符
    struct sockaddr_in broadcataddr; 
    socklen_t addrlen = sizeof(broadcataddr);

    //第一步:创建套接字
    if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    {
        perror("fail to socket");
        exit(1);
    }

    //第二步:填充广播信息结构体
    broadcataddr.sin_family = AF_INET;
    broadcataddr.sin_addr.s_addr = inet_addr(argv[1]); //192.168.3.255 255.255.255.255
    broadcataddr.sin_port = htons(atoi(argv[2]));

    //第三步:将套接字与广播信息结构体绑定
    if(bind(sockfd, (struct sockaddr *)&broadcataddr, addrlen) < 0)
    {
        perror("fail to bind");
        exit(1);
    }

    //第四步:进行通信
    char text[32] = "";
    struct sockaddr_in sendaddr;

    while(1)
    {
        if(recvfrom(sockfd, text, sizeof(text), 0, (struct sockaddr *)&sendaddr, &addrlen) < 0)
        {
            perror("fail to recvfrom");
            exit(1);
        }
        
        printf("[%s - %d]: %s\n", inet_ntoa(sendaddr.sin_addr), ntohs(sendaddr.sin_port), text);
    }

    return 0;
}

执行结果

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

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

相关文章

DirClass

DirClass 通过分析&#xff0c;发现当接收到DirClass远控指令后&#xff0c;样本将返回指定目录的目录信息&#xff0c;返回数据中的远控指令为0x2。 相关代码截图如下&#xff1a; DelDir 通过分析&#xff0c;发现当接收到DelDir远控指令后&#xff0c;样本将删除指定目录…

46. UE5 RPG 实现角色死亡效果

在上一篇文章中&#xff0c;我们实现了敌人受到攻击后会播放受击动画&#xff0c;并且还给角色设置了受击标签。并在角色受击时&#xff0c;在角色身上挂上受击标签&#xff0c;在c里&#xff0c;如果挂载了此标签&#xff0c;速度将降为0 。 受击有了&#xff0c;接下来我们将…

机器学习之基于Jupyter多种混合模型的糖尿病预测

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景 随着现代生活方式的改变&#xff0c;糖尿病的患病率在全球范围内呈现上升趋势。糖尿病是一种慢性代谢…

【R语言从0到精通】-4-回归建模

通过之前的文章&#xff0c;我们已经基本掌握了R语言的基本使用方法&#xff0c;那从本次教程开始&#xff0c;我们开始聚焦如何使用R语言进行回归建模。 4.1 回归简介 回归分析是一种统计学方法&#xff0c;用于研究两个或多个变量之间的相互关系和依赖程度。它可以帮助我们了…

4G工业路由器快递柜应用案例(覆盖所有场景)

快递柜展示图 随着电商的蓬勃发展,快递行业迎来高速增长。为提高快递效率、保障快件安全,智能快递柜应运而生。但由于快递柜部署环境复杂多样,网络接入成为一大难题。传统有线宽带难以覆盖所有场景,而公用WiFi不稳定且存在安全隐患。 星创易联科技有限公司针对这一痛点,推出了…

【智能算法】人类进化优化算法(HEOA)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献5.代码获取 1.背景 2024年&#xff0c;J Lian受到人类进化启发&#xff0c;提出了人类进化优化算法&#xff08;Human Evolutionary Optimization Algorithm, HEOA&#xff09;。 2.算法原理 2.1算法思想 …

Linux提示:mount: 未知的文件系统类型“ntfs”

mount: 未知的文件系统类型“ntfs” 在Linux系统中&#xff0c;如果遇到“mount: 未知的文件系统类型‘ntfs’”的错误&#xff0c;这通常意味着您的系统没有安装支持NTFS文件系统的软件。为了挂载NTFS文件系统&#xff0c;您需要安装ntfs-3g软件包。以下是如何在不同Linux发行…

python学习笔记-02

变量和数据类型 程序中运用变量存储数据&#xff0c;python是一门强类型语言&#xff0c;赋值时不需要指定数据类型。 1.变量的定义 语法格式&#xff1a;变量名数据 a10 print(a) a哈哈 print(a)python中基本数据类型&#xff1a; 数字(num)&#xff1a;int(有符号整数)、lo…

Java_方法引用

方法引用就是把已经有的方法拿过来用&#xff0c;当作函数式接口中抽象方法的方法体。 条件&#xff1a; 1.引用处需要是函数式接口 2.被引用的方法需要已经存在 3.被引用的方法的形参和返回值需要跟抽象方法的形参和返回值保持一致 4.被引用方法的功能需要满足当前的要求 简…

122. Kafka问题与解决实践

文章目录 前言顺序问题1. 为什么要保证消息的顺序&#xff1f;2.如何保证消息顺序&#xff1f;3.出现意外4.解决过程 消息积压1. 消息体过大2. 路由规则不合理3. 批量操作引起的连锁反应4. 表过大 主键冲突数据库主从延迟重复消费多环境消费问题后记 前言 假如有家公司是做餐饮…

Java性能优化(五)-多线程调优-Lock同步锁的优化

作者主页&#xff1a; &#x1f517;进朱者赤的博客 精选专栏&#xff1a;&#x1f517;经典算法 作者简介&#xff1a;阿里非典型程序员一枚 &#xff0c;记录在大厂的打怪升级之路。 一起学习Java、大数据、数据结构算法&#xff08;公众号同名&#xff09; ❤️觉得文章还…

python基础---面向对象相关知识

面向对象 可以把数据以及功能打包为一个整体 类: 名称属性(数据)方法 class Person:def __init__(self, name, age):self.age ageself.name namedef print_info:print(self.name, self.age)定义 #经典类 class Dog1:pass# 新式类 class Dog2(object):pass在python3里面这…

[leetcode] 67. 二进制求和

文章目录 题目描述解题方法模拟java代码复杂度分析 相似题目 题目描述 给你两个二进制字符串 a 和 b &#xff0c;以二进制字符串的形式返回它们的和。 示例 1&#xff1a; 输入:a "11", b "1" 输出&#xff1a;"100"示例 2&#xff1a; 输…

QML 本地存储(Setting,sqlite)

Qt hello - 专注于Qt的技术分享平台 QML 原生的储存方有两种&#xff1a; 1&#xff0c;Settings 跟QWidget 中的QSettings 一样&#xff0c;可以简单的存储一些配置。 2&#xff0c;Sqlite sqlite数据库。可以存储一些复杂的数据。 一&#xff0c;Settings 我们以一个按钮的位…

自动语音识别

⚠申明&#xff1a; 未经许可&#xff0c;禁止以任何形式转载&#xff0c;若要引用&#xff0c;请标注链接地址。 全文共计3077字&#xff0c;阅读大概需要3分钟 &#x1f308;更多学习内容&#xff0c; 欢迎&#x1f44f;关注&#x1f440;【文末】我的个人微信公众号&#xf…

学习笔记:【QC】Android Q qmi扩展nvReadItem/nvWriteItem

一、qmi初始化 流程图 初始化流程: 1、主入口&#xff1a; vendor/qcom/proprietary/qcril-hal/qcrild/qcrild/rild.c int main(int argc, char **argv) { const RIL_RadioFunctions *(*rilInit)(const struct RIL_Env *, int, char **); rilInit RIL_Init; funcs rilInit…

深度学习之基于Matlab神经网络的活体人脸和视频人脸识别系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景 人脸识别技术作为生物识别技术的一种&#xff0c;近年来得到了广泛的关注和应用。与传统的身份认证方…

小程序预览或上传代码时,遇到app.json未找到某个wxml文件的解决方法

uniapp小程序&#xff0c;点击预览或者是上传代码&#xff0c;遇到app.json无法找到某个wxml文件的解决方法&#xff1a;清缓存 问题&#xff1a; message&#xff1a;Error: app.json: 未找到 ["subPackages"][3]["pages"][3] 对应的 subPackages4/pages/…

RTT潘多拉开发板上实现电源管理

简介 随着物联网(IoT)的兴起&#xff0c;产品对功耗的需求越来越强烈。作为数据采集的传感器节点通常需要在电池供电时长期工作&#xff0c;而作为联网的SOC也需要有快速的响应功能和较低的功耗。 在产品开发的起始阶段&#xff0c;首先考虑是尽快完成产品的功能开发。在产品…

【负载均衡在线OJ项目日记】编译与日志功能开发

目录 日志功能开发 常见的日志等级 日志功能代码 编译功能开发 创建子进程和程序替换 重定向 编译功能代码 日志功能开发 日志在软件开发和运维中起着至关重要的作用&#xff0c;目前我们不谈运维只谈软件开发&#xff1b;日志最大的作用就是用于故障排查和调试&#x…