网络编程 | UDP广播通信

1、什么是广播

        在上一篇博客文章中已经对UDP进行了详细的说明介绍及如何编程实现。本文将接着上一文的内容,在其基础上,对UDP的知识体系进一步深入的讲解。

        网络编程 | UDP套接字通信及编程实现经验教程-CSDN博客

        例子:在一些中小学的操场中,通常会安装大功率喇叭用于播放广播体操音乐和上下课铃声,现在操场内有若干学生,当铃声响起时,学生们根据听到的指令开始做体操动作。

        这个场景可以用来解释网络通信中的“广播”概念。但如果操场内只有一个学生,那么虽然广播内容(如铃声或指令)仅由这一个学生接收,这个情况被称为单播,但在技术定义上,这种情况仍然被视为广播因为广播的本质在于信息的发送方式——即信息被发送到特定范围内的所有潜在接收者,而不论实际接收者的数量如何。在上面的这个例子中,“操场”代表了广播地址范围,喇叭作为广播的发送端,而位于操场内的学生则为广播的接收端。

  • 单播是指数据包被发送给单一的接收方,即每次通信只针对一个目标。
  • 广播则是指将信息同时发送给特定范围(如局域网)内的所有主机。即使该范围内实际上只有一个接收者,只要发送方式是面向所有可能接收者的,它就属于广播的形式。

        因此,在上述操场的例子中,无论当前有多少学生在场,喇叭播放的铃声都是以广播形式发送出去的,区别只在于实际接收到广播的人数不同而已。这一过程与计算机网络中使用UDP协议进行广播通信的原理相似,其中信息被发送到指定的网络段,可供该段内的所有设备接收。

2、广播的特点

        只有用户数据报套接字(使用UDP协议)才能广播。UDP(用户数据报协议)广播是一种网络通信方式,它允许信息在同一局域网内的所有设备之间共享。

①、高效性:广播消息只需发送一次,即可被局域网内的所有设备接收到,这使得在需要通知多个接收者时非常高效。

②、无连接的传输:UDP本身是无连接的协议,这意味着在发送广播消息之前不需要建立与接收方的连接。因此,它可以快速地发送数据,但不保证数据能够成功到达或按顺序到达。

③、不可靠的数据传输:由于UDP不提供确认机制、重传机制或流量控制,所以它不能保证消息一定会被接收方收到。如果可靠性是关键需求,则可能需要额外的上层协议来确保消息的成功传输。

④、有限的作用范围:UDP广播通常限制在本地子网内,即只能在同一局域网中的设备之间进行传播。这是因为路由器默认情况下不会转发广播消息到其他网络,以避免不必要的网络流量和潜在的安全问题。

⑤、使用特殊的目的地址:在IPv4中,广播地址通常是子网中主机部分全为1的地址(例如,在子网192.168.1.0/24中,广播地址为192.168.1.255)。而IPv6不支持传统的广播概念,取而代之的是多播。

⑥、适合特定场景:UDP广播非常适合于那些需要向网络上的所有设备发送少量信息的应用程序,如网络发现服务、动态主机配置协议(DHCP)等。

⑦、安全考虑:因为任何设备都可以监听并响应广播消息,所以在设计使用广播的应用程序时,需要考虑到潜在的安全风险,比如防止未经授权的访问或攻击。

        以192.168.1.0网段为例:***.***.***.255 代表该网段的广播地址。发送给该地址的数据包,可被网段内的所有主机接收。

        比如博主当前PC所处的局域网段 是 192.168.1.0 ,那么广播地址就是 192.168.1.255

sendto("你好", 192.168.1.255);

3、广播通信流程

        因广播是基于UDP实现的,故广播的发送端和接收端的实现流程,与常见的UDP的客户端与服务器的流程大致相同。

4、广播通信的程序

(1)、广播发送端

①、创建数据报套接字

int socketfd = socket(AF_INET, SOCK_DGRAM, 0);

②、设置socketfd套接字文件描述符的属性为广播 。(也就是允许发送广播数据包)

        SO_BROADCAST -----> 使用广播方式传送

int broadcast_flag = 1;
setsockopt(sockfd , SOL_SOCKET, SO_BROADCAST, &broadcast_flag, sizeof(broadcast_flag));

③、发送数据 ,指定接收方为广播地址

struct sockaddr_in sendAddr;
sendAddr.sin_family = AF_INET;
sendAddr.sin_port = htons(10000);
sendAddr.sin_addr.s_addr = inet_addr("192.168.1.255");//一定是广播地址,广播发送
sendto(sockfd,buf, strlen(buf), 0, (struct sockaddr*)&sendAddr, sizeof(sendAddr));

④、关闭套接字

close(socketfd);

(2)、广播接收端

①、创建用户数据报套接字

int socketfd = socket(AF_INET, SOCK_DGRAM, 0);

②、绑定(192.168.1.255)广播IP地址和端口号 (10000)

        注意:绑定的端口必须和发送方指定的端口相同

struct sockaddr_in ownAddr;
ownAddr.sin_family = AF_INET;
ownAddr.sin_port = htons(10000);
//uint32_t htonl(uint32_t hostlong);  将 主机IP转为 网络IP
ownAddr.sin_addr.s_addr = htonl(INADDR_ANY);//INADDR_ANY(0.0.0.0) 代表本机所有的地址  //inet_addr("192.168.1.255");

③、接收数据

recvfrom(socketfd, ...);

④、关闭套接字

close(socketfd);

(3)、广播实现程序

①、广播发送端
#include<stdio.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>int main(int argc, char **argv)
{printf("广播发送端(UDP协议)...............\n");//1、创建数据报套接字int socketfd = socket(AF_INET, SOCK_DGRAM, 0);if(socketfd == -1){perror("socket error");return -1;}//2、设置套接字文件描述符socketfd的属性为广播(也就是允许发送广播数据包) int broadcast_flag=1;setsockopt(socketfd,SOL_SOCKET, SO_BROADCAST, &broadcast_flag, sizeof(broadcast_flag));//3、发送数据,并且指定接收方为广播地址struct sockaddr_in sendAddr;//IPV4地址结构体变量sendAddr.sin_family = AF_INET;sendAddr.sin_port = htons(10000);sendAddr.sin_addr.s_addr = inet_addr("192.168.1.255");//一定是广播地址,广播发送while(1){char buf[1024]={0};printf("data:");scanf("%s",buf);sendto(socketfd,buf, strlen(buf), 0, (struct sockaddr *)&sendAddr, sizeof(sendAddr));}close(socketfd);return 0;    
}
②、广播接收端
#include<stdio.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>int main(int argc, char **argv)
{printf("广播接收端(UDP协议)...............\n");//1、创建数据报套接字int socketfd = socket(AF_INET, SOCK_DGRAM, 0);if(socketfd == -1){perror("socket error");return -1;}//2、绑定(192.168.1.255)广播IP地址和端口号 (10000)struct sockaddr_in ownAddr;ownAddr.sin_family = AF_INET;ownAddr.sin_port = htons(10000); //s unsigned short int     ownAddr.sin_addr.s_addr = htonl(INADDR_ANY);//INADDR_ANY(0.0.0.0) 代表本机所有的地址  //inet_addr("192.168.1.255");bind(socketfd, (struct sockaddr *)&ownAddr, sizeof(ownAddr));struct sockaddr_in otherAddr;int len = sizeof(struct sockaddr_in);while(1){char buf[1024]={0};recvfrom(socketfd, buf, sizeof(buf), 0, (struct sockaddr *)&otherAddr, &len);printf("来自 %s:%u  recv:%s\n",inet_ntoa(otherAddr.sin_addr),ntohs(otherAddr.sin_port),buf);}close(socketfd);return 0;    
}

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

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

相关文章

Count Sketch--计数草图

背景 Count Sketch 是一种空间高效的概率型数据结构&#xff0c;由 Moses Charikar、Kevin Chen 和 Martin Farach-Colton 在 2002 年提出&#xff0c;用于估计数据流中元素的频率&#xff0c;也可用于解决重击者问题。 原理 算法结构 参数设定&#xff1a;Count Sketch算法…

2025.1.17——三、SQLi regexp正则表达式|

题目来源&#xff1a;buuctf [NCTF2019]SQLi1 目录 一、打开靶机&#xff0c;整理信息 二、解题思路 step 1&#xff1a;正常注入 step 2&#xff1a;弄清关键字黑名单 1.目录扫描 2.bp爆破 step 3&#xff1a;根据过滤名单构造payload step 4&#xff1a;regexp正则注…

搭建一个基于Spring Boot的书籍学习平台

搭建一个基于Spring Boot的书籍学习平台可以涵盖多个功能模块&#xff0c;例如用户管理、书籍管理、学习进度跟踪、笔记管理、评论和评分等。以下是一个简化的步骤指南&#xff0c;帮助你快速搭建一个基础的书籍学习平台。 — 1. 项目初始化 使用 Spring Initializr 生成一个…

【Linux 之一 】Linux常用命令汇总

Linux常用命令 ./catcd 命令chmodclearcphistoryhtoplnmkdirmvpwdrmtailunamewcwhoami 我从2021年4月份开始才开始真正意义上接触Linux&#xff0c;最初学习时是一脸蒙圈&#xff0c;啥也不会&#xff0c;啥也不懂&#xff0c;做了很多乱七八糟&#xff0c;没有条理的笔记。不知…

Hexo + NexT + Github搭建个人博客

文章目录 一、 安装二、配置相关项NexT config更新主题主题样式本地实时预览常用命令 三、主题设置1.侧边栏2.页脚3.帖子发布字数统计 4.自定义自定义页面Hexo 的默认页面自定义 404 页自定义样式 5.杂项搜索服务 四、第三方插件NexT 自带插件评论系统阅读和访问人数统计 五、部…

开发神器之cursor

文章目录 cursor简介主要特点 下载cursor页面的简单介绍切换大模型指定ai学习的文件指定特定的代码喂给ai创建项目框架文件 cursor简介 Cursor 是一款专为开发者设计的智能代码编辑器&#xff0c;集成了先进的 AI 技术&#xff0c;旨在提升编程效率。以下是其主要特点和功能&a…

当前目录不是一个git仓库/远程仓库已经有了一些你本地没有的更改

目录 问题1&#xff1a;问题2&#xff1a;解决1解决2 问题1&#xff1a; fatal: not a git repository (or any parent up to mount point /) Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set). # 初始化 Git 仓库 git init需要到本地目录下先添加…

差异基因富集分析(R语言——GOKEGGGSEA)

接着上次的内容&#xff0c;上篇内容给大家分享了基因表达量怎么做分组差异分析&#xff0c;从而获得差异基因集&#xff0c;想了解的可以去看一下&#xff0c;这篇主要给大家分享一下得到显著差异基因集后怎么做一下通路富集。 1.准备差异基因集 我就直接把上次分享的拿到这…

BGP边界网关协议(Border Gateway Protocol)路由引入、路由反射器

一、路由引入背景 BGP协议本身不发现路由&#xff0c;因此需要将其他协议路由&#xff08;如IGP路由等&#xff09;引入到BGP路由表中&#xff0c;从而将这些路由在AS之内和AS之间传播。 BGP协议支持通过以下两种方式引入路由&#xff1a; Import方式&#xff1a;按协议类型将…

使用FFmpeg和Python将短视频转换为GIF的使用指南

使用FFmpeg和Python将短视频转换为GIF的使用指南 在数字时代&#xff0c;GIF动图已成为表达情感和分享幽默的重要媒介。无论是社交媒体上的搞笑片段还是创意项目中的视觉效果&#xff0c;GIF都能迅速抓住观众的注意力。然而&#xff0c;很多人不知道如何将短视频转换为GIF。本…

LLM - 大模型 ScallingLaws 的迁移学习与混合训练(PLM) 教程(3)

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/145212097 免责声明&#xff1a;本文来源于个人知识与公开资料&#xff0c;仅用于学术交流&#xff0c;欢迎讨论&#xff0c;不支持转载。 Scalin…

解决leetcode第3418题机器人可以获得的最大金币数

3418.机器人可以获得的最大金币数 难度&#xff1a;中等 问题描述&#xff1a; 给你一个mxn的网格。一个机器人从网格的左上角(0,0)出发&#xff0c;目标是到达网格的右下角(m-1,n-1)。在任意时刻&#xff0c;机器人只能向右或向下移动。 网格中的每个单元格包含一个值coin…

蓝桥杯 Python 组知识点容斥原理

容斥原理 这张图初中或者高中数学课应该画过 也就是通过这个简单的例子引出容斥原理的公式 这张图的面积&#xff1a;s1 s3 s7 - 2 * s2 - 2 * s4 - 2 * s6 3 * s5 通过此引导出容斥原理公式 那么下面来一起看看题目 题目描述 给定 n,m 请求出所有 n 位十进制整数中有多…

GitLab:添加SSH密钥之前,您不能通过SSH来拉取或推送项目代码

1、查看服务器是否配置过 [rootkingbal-ecs-7612 ~]# cd .ssh/ [rootkingbal-ecs-7612 .ssh]# ls authorized_keys id_ed25519 id_ed25519.pub id_rsa id_rsa.pub2、创建密钥 $ ssh-keygen -t rsa -C kingbalkingbal.com # -C 后写你的邮箱 一路回车 3、复制密钥 [rootk…

day10_Structured Steaming

文章目录 Structured Steaming一、结构化流介绍&#xff08;了解&#xff09;1、有界和无界数据2、基本介绍3、使用三大步骤(掌握)4.回顾sparkSQL的词频统计案例 二、结构化流的编程模型&#xff08;掌握&#xff09;1、数据结构2、读取数据源2.1 File Source2.2 Socket Source…

【设计模式】 单例模式(单例模式哪几种实现,如何保证线程安全,反射破坏单例模式)

单例模式 作用&#xff1a;单例模式的核心是保证一个类只有一个实例&#xff0c;并且提供一个访问实例的全局访问点。 实现方式优缺点饿汉式线程安全&#xff0c;调用效率高 &#xff0c;但是不能延迟加载懒汉式线程安全&#xff0c;调用效率不高&#xff0c;能延迟加载双重检…

无公网IP 实现外网访问本地 Docker 部署 Navidrome

Navidrome 是一款可以在 macOS、Linux、Windows以及 Docker 等平台上运行的跨平台开源音乐服务器应用&#xff0c;它支持传输常见的 MP3、FLAC、WAV等音频格式。允许用户通过 Web 界面或 API 进行音乐库的管理和访问。本文就介绍如何快速在 Linux 系统使用 Docker 进行本地部署…

解决conda create速度过慢的问题

问题 构建了docker容器 想在容器中创建conda环境&#xff0c;但是conda create的时候速度一直很慢 解决办法 宿主机安装的是anaconda 能正常conda create,容器里安装的是miniforge conda create的时候速度一直很慢&#xff0c;因为容器和宿主机共享网络了&#xff0c;宿主机…

【Hive】新增字段(column)后,旧分区无法更新数据问题

TOC 【一】问题描述 Hive修改数据表结构的需求&#xff0c;比如&#xff1a;增加一个新字段。 如果使用如下语句新增列&#xff0c;可以成功添加列col1。但如果数据表tb已经有旧的分区&#xff08;例如&#xff1a;dt20190101&#xff09;&#xff0c;则该旧分区中的col1将为…

【Python】Selenium根据网页页面长度,模拟向下滚动鼠标,直到网页底部的操作

最近在弄selenium的爬取的过程中&#xff0c;我发现一些网站上的表格&#xff0c;是需要手动拉到底部才能加载完成的。 如果没有拉到底部&#xff0c;那么在获取网页表格的时候&#xff0c;表格就会只有显示的一部分&#xff0c;页面就不完整。 所以我就整理了一些模拟滚动鼠…