UDP特性之广播

news2024/11/25 18:33:40

UDP特性之广播

  • 1. 广播的特点
  • 2. 设置广播属性
  • 3. 广播通信流程
  • 4. 通信代码
    • 总结

1. 广播的特点

广播的UDP的特性之一,通过广播可以向子网中多台计算机发送消息,并且子网中所有的计算机都可以接收到发送方发送的消息,每个广播消息都包含一个特殊的IP地址,这个IP中子网内主机标志部分的二进制全部为1 (即点分十进制IP的最后一部分是255)。点分十进制的IP地址每一部分是1字节,最大值为255,比如:192.168.1.100

  • 前两部分192.168表示当前网络是局域网
  • 第三部分1表示局域网中的某一个网段,最大值为 255
  • 第四部分100用于标记当前网段中的某一台主机,最大值为255
  • 每个网段都有一个特殊的广播地址,即:192.168.xxx.255

广播分为两端,即数据发送端和数据接收端,通过广播的方式发送数据,发送端和接收端的关系是 1:N

  • 发送广播消息的一端,通过广播地址,可以将消息同时发送到局域网的多台主机上(数据接收端)

  • 在发送广播消息的时候,必须要把数据发送到广播地址上

  • 广播只能在局域网内使用,广域网是无法使用UDP进行广播的

  • 只要发送端在发送广播消息,数据接收端就能收到广播消息,消息的接收是无法拒绝的,除非将接收端的进程关闭,就接收不到了。

UDP的广播和日常生活中的广播是一样的,都是一种快速传播消息的方式,因此广播的开销很小,发送端使用一个广播地址,就可以将数据发送到多个接收数据的终端上,如果不使用广播,就需要进行多次发送才能将数据分别发送到不同的主机上。

2. 设置广播属性

基于UDP虽然可以进行数据的广播,但是这个属性默认是关闭的,如果需要对数据进行广播,那么需要在广播端代码中开启广播属性,需要通过套接字选项函数进行设置,该函数原型为:

int setsockopt(int sockfd, int level, int optname, 	const void *optval, socklen_t optlen);
  • 参数:
    • sockfd:进行UDP通信的文件描述符
    • level: 套接字级别,需要设置为 SOL_SOCKET
    • optname:选项名,此处要设置udp的广播属性,该参数需要指定为:SO_BROADCAST
    • optval:如果是设置广播属性,该指针实际指向一块int类型的内存
      • 该整型值为0:关闭广播属性
      • 该整形值为1:打开广播属性
    • optlen:optval指针指向的内存大小,即:sizeof(int)
  • 返回值:函数调用成功返回0,失败返回-1

3. 广播通信流程

如果使用UDP在局域网范围内进行消息的广播,一般情况下广播端只发送数据,接收端只接受广播消息。因此在数据接收端需要绑定固定的端口,广播端则不需要手动绑定固定端口,自动随机绑定即可。
在这里插入图片描述
(上面这个图的ip应该是画错了,ip应该都是不一样的)

  • 数据发送端
  1. 创建通信的套接字
// 第二个参数是 SOCK_DGRAM, 第三个参数0表示使用报式协议中的udp
int fd = socket(AF_INET, SOCK_DGRAM, 0);
  1. 主动发送数据不需要手动绑定固定端口(自动随机分配就可以了),因此直接设置广播属性
int opt  = 1;
setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &opt, sizeof(opt));
  1. 使用广播地址发送广播数据到接收端绑定的固定端口上
sendto();
  1. 关闭套接字(文件描述符)
close(fd);
  • 数据接收端
  1. 创建通信的套接字
// 第二个参数是 SOCK_DGRAM, 第三个参数0表示使用报式协议中的udp
int fd = socket(AF_INET, SOCK_DGRAM, 0);
  1. 因为是被动接收数据的一端,所以必须要绑定固定的端口和本地IP地址
bind();
  1. 接收广播消息
recvfrom();
  1. 关闭套接字(文件描述符)
close(fd);

4. 通信代码

这里有一个很明显的误区,下面我用删除线标注了。广播的时候,跟udp、tcp通信存在不同,后者通信的时候,一般是服务端bind。但是广播的时候,是接收端bind!!!

广播端 (也就是服务端)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>

int main()
{
    // 1. 创建通信的套接字
    int fd = socket(AF_INET, SOCK_DGRAM, 0);
    if(fd == -1)
    {
        perror("socket");
        exit(0);
    }

    // 2. 设置广播属性
    int opt  = 1;
    setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &opt, sizeof(opt));

    char buf[1024];
    struct sockaddr_in cliaddr;
    int len = sizeof(cliaddr);
    cliaddr.sin_family = AF_INET;
    cliaddr.sin_port = htons(9999); // 接收端需要绑定9999端口
    // 只要主机在254网段, 并且绑定了9999端口, 这个接收端就能收到广播消息
	// 这是一个局域网ip
    inet_pton(AF_INET, "10.82.254.255", &cliaddr.sin_addr.s_addr);
    // 3. 通信
    int num = 0;
    while(1)
    {
        sprintf(buf, "hello, client...%d\n", num++);
        // 数据广播
        sendto(fd, buf, strlen(buf)+1, 0, (struct sockaddr*)&cliaddr, len);
        printf("发送的广播的数据: %s\n", buf);
        sleep(1);
    }

    close(fd);

    return 0;
}

注意事项:发送广播消息一端必须要开启UDP的广播属性,并且发送消息的地址必须是当前发送端所在网段的广播地址,这样才能通过调用一个消息发送函数将消息同时发送N台接收端主机上。

发送方式设置广播地址。

接收端 (也就是客户端)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>

int main()
{
    // 1. 创建通信的套接字
    int fd = socket(AF_INET, SOCK_DGRAM, 0);
    if(fd == -1)
    {
        perror("socket");
        exit(0);
    }

    // 2. 通信的套接字和本地的IP与端口绑定
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(9999);    // 大端
    addr.sin_addr.s_addr = INADDR_ANY;  // 0.0.0.0
    int ret = bind(fd, (struct sockaddr*)&addr, sizeof(addr));
    if(ret == -1)
    {
        perror("bind");
        exit(0);
    }

    char buf[1024];
    // 3. 通信
    while(1)
    {
        // 接收广播消息
        memset(buf, 0, sizeof(buf));
        // 阻塞等待数据达到
        recvfrom(fd, buf, sizeof(buf), 0, NULL, NULL);
        printf("接收到的广播消息: %s\n", buf);
    }

    close(fd);

    return 0;
}


对于接收广播消息的一端,必须要绑定固定的端口,并由广播端将广播消息发送到这个端口上,因此所有接收端都应绑定相同的端口,这样才能同时收到广播数据。

接收端的bind的ip

  • 如果是INADDR_ANY,可以实现接收来自任何IP地址的UDP广播消息
  • 如果是具体的ip,接收特定网络接口上的UDP广播消息

总结

  • 发送的ip统一填广播地址,比如10.82.254.255
  • 接收方的bind的ip
    • 要么INADDR_ANY
    • 要么具体的ip(这个好像不行,留个疑问)

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

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

相关文章

单机环境下一人一单

优惠券秒杀 添加优惠卷 店铺发布优惠券又分为平价券和特价券, 平价券可以任意购买而特价券需要秒杀抢购(限制数量和时间) tb_voucher(平价券): 优惠券的基本信息 tb_seckill_voucher(秒杀券): 有voucher_id字段表示具有优惠卷的基本信息,此外还有库存,开始抢购时间,结束抢购…

世界第一个语言不通的人是如何沟通的?

引言&#xff1a;语言是人类交流的重要工具&#xff0c;但在人类历史的某个时刻&#xff0c;肯定会有这样一位勇敢的先驱&#xff0c;他成为了世界上第一个语言不通的人。那么在他面临交流难题时&#xff0c;他是如何与他人沟通的呢&#xff1f;本文将对此进行探索。主体&#…

Nginx+Tomcat实现负载均衡和动静分离

目录 前瞻 动静分离和负载均衡原理 实现方法 实验&#xff08;七层代理&#xff09; 部署Nginx负载均衡服务器(192.168.75.50:80) 部署第一台Tomcat应用服务器&#xff08;192.168.75.60:8080&#xff09; 多实例部署第二台Tomcat应用服务器&#xff08;192.168.75.70:80…

【超图】SuperMap iClient3D for WebGL/WebGPU —— 单体gltf模型与Blender中的方向对应关系

作者&#xff1a;taco 在很多包含动画的场景中&#xff0c;像模拟小人的行走、模拟火车的轨迹运行&#xff0c;又或者是模拟风力发电等等等。我们通常会加一些动画模型到里面。而有的时候可能会出现&#xff0c;这火车怎么倒着走啊&#xff01;这人怎么头朝下啊。这种方向的问题…

【MySQL】MySQL库的增删查改

文章目录 1.库的操作1.1创建数据库1.2创建数据库案例 2.字符集和校验规则2.1查看系统默认字符集以及校验规则2.2查看数据库支持的字符集2.3查看数据库支持的字符集校验规则2.4校验规则对数据库的影响 3.操纵数据库3.1查看数据库3.2显示创建语句3.3修改数据库3.4数据库删除3.5备…

DevOps搭建(五)-JDK安装详细步骤

1、官网下载 官方网站下载JDK&#xff0c;这里我们安装JDK8 https://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html 点击上图中的Java SE Downloads项目&#xff0c;也可直接点击下面链接进入&#xff1a; Java Downloads | Oracle 往下滚…

Android14创建Pixel6 Pro模拟器(一百七十)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

C++设计模式-Builder 构建器

通过“对象创建” 模式绕开new&#xff0c;来避免对象创建&#xff08;new&#xff09;过程中所导致的紧耦合&#xff08;依赖具体类&#xff09;&#xff0c;从而支持对象创建的稳定。它是接口抽象之后的第一步工作。 一、动机 在软件系统中&#xff0c;有时候面临着“一个复…

STM32--Wi-Fi插座_风扇_灯

项目需求 两个互相通信的双方&#xff0c;波特率必须相同!!!!!! 通过 ESP8266 模块&#xff0c;实现手机控制 wifi 插座 / 风扇 / 灯。 项目设计 串口 1 用于与 ESP8266 通讯&#xff0c;串口 2 连接 PC &#xff0c;用于打印 log &#xff0c;查看系统状态。 项目实现 注意&a…

网络安全项目实战(四)--报文检测

8. TCP/UDP 段 目标 了解 TCP 段头的组织结构了解 UDP 段头的组织结构掌握 TCP/UDP 段的解析方式 8.1. UDP 段格式 下图是UDP的段格式&#xff08;该图出自[TCPIP]&#xff09;。 8.2. UDP头部 //UDP头部&#xff0c;总长度8字节// /usr/include/linux/udp.h struct udphdr …

拦截器实现指定的IP白名单进行访问规定的Controller

需求&#xff1a;只允许内网的IP&#xff08;也就是IP白名单&#xff09;进行访问VideoController和ImgController&#xff0c;其余的FontController可以随便访问不做限制 总体的项目结构&#xff1a; 1、先写好业务代码三个Controller 访问的路径分别是&#xff1a; /api/…

【三视图】咒语 生成人物

revAnimated_v122.safetensors 杰作&#xff0c;最佳质量&#xff0c;角色设计&#xff0c;三视图&#xff0c;前视图&#xff0c;侧视图&#xff0c;后视觉&#xff0c;呆萌&#xff0c;可爱&#xff0c;简单的背景&#xff0c; (badhandv4:1.4),ng_deepnegative_v1_75t,negat…

qt-C++笔记之模拟实现一个linux终端窗口

qt-C笔记之模拟实现一个linux终端窗口 code review! 文章目录 qt-C笔记之模拟实现一个linux终端窗口一.运行二.main.cpp三.不足&#xff0c;待改进点 一.运行 二.main.cpp 代码 #include <QApplication> #include <QPlainTextEdit> #include <QLineEdit>…

新版Spring Security6.2 - Digest Authentication

前言&#xff1a; 书接上文&#xff0c;上次翻译basic的这页&#xff0c;这次翻译Digest Authentication这页。 摘要认证-Digest Authentication 官网的警告提示&#xff1a;不应在应用程序中使用摘要式身份验证&#xff0c;因为它不被认为是安全的。最明显的问题是您必须以…

聊聊Java中的异常

什么是异常 关于Java的异常&#xff0c;我们认为符合大致分为以下几种情况: 程序逻辑运行结果不符合预期。程序执行时抛出各种exception。因为各种原因导致服务崩溃。 Java异常类体系结构如下图所示: Exception和Error的区别 Exception Exception或者Exception自类的异常对…

有关爬虫http/https的请求与响应

简介 HTTP协议&#xff08;HyperText Transfer Protocol&#xff0c;超文本传输协议&#xff09;&#xff1a;是一种发布和接收 HTML页面的方法。 HTTPS&#xff08;Hypertext Transfer Protocol over Secure Socket Layer&#xff09;简单讲是HTTP的安全版&#xff0c;在HTT…

【亲测】获取百度智能云access_token并存储,百度智能云access_token有效期

百度智能云服务内置很多api接口&#xff08;文字识别&#xff0c;企业信息识别&#xff0c;等&#xff09;&#xff0c;所有百度智能云自带的接口都会用到百度的access_token 第一步&#xff1a;登录百度智能云管理中心 第二步&#xff1a;创建账户&#xff0c;完整身份认证 …

Binder IPC通讯流程 摘要

一次完整的 Binder IPC 通信过程通常是这样&#xff1a; 首先 Binder 驱动在内核空间创建一个数据接收缓存区&#xff1b;接着在内核空间开辟一块内核缓存区&#xff0c;建立内核缓存区和内核中数据接收缓存区之间的映射关系&#xff0c;以及内核中数据接收缓存区和接收进程用…

Leetcode2048. 下一个更大的数值平衡数

Every day a Leetcode 题目来源&#xff1a;2048. 下一个更大的数值平衡数 解法1&#xff1a;枚举 这种题不能想复杂了&#xff0c;枚举大法好。 代码&#xff1a; /** lc appleetcode.cn id2048 langcpp** [2048] 下一个更大的数值平衡数*/// lc codestart class Soluti…

中医电子处方管理系统软件,中医配方模板一键生成软件操作教程

一、前言&#xff1a; 在中医开电子处方时&#xff0c;如果能够使用配方模板功能&#xff0c;则可以节省很多时间。使用配方模板一键导入&#xff0c;几秒即可完成开单。 下面就以佳易王电子处方管理系统软件V17.1版本为例说明&#xff0c;其他版本可以参考&#xff0c;软件下…