一,广播简介

从上述讲的例⼦中,不管是TCP协议还是UDP协议,都是”单播”, 就是”点对点”的进⾏通信,如果要对网络里面的所有主机进⾏通信,实现”点对多”的通信,我们可以使用UDP中的⼴播通信。
理论上可以像播放电视节目⼀样在整个Internet 上发送广播数据,但是几乎没有路由器转发广播数据,所以,广播程序只能应用在本地子网中。

广播的特点:

1.⼴播需要有发送⽅和接收⽅,必须有⼀些线程在机器上监听到来的数据。⼴播的缺点是如果有多个进程都发送⼴播数据,⽹络就会阻塞,⽹络性能便会受到影响。
2.⼴播发送不是循环给⽹络中的每⼀个IP发送数据,而是给⽹络中⼀个特定的IP发送信息,这个IP就是⼴播地址,⼴播发送方:使⽤setsockopt打开SO_BROADCAST, 设置广播地址 255.255.255.255,设置⼴播端口号。广播接收方:将套接字绑定到指定的广播端口号, 监听数据到来。
3.⼴播数据发送只能采⽤UDP协议,⼴播UDP与单播UDP的区别就是IP地址不同,⼴播使⽤广播地址255.255.255.255,将消息发送到在同⼀广播网络上的每个主机。

广播的实现:

发送方:
1.调用 setsockopt() 打开 SO_BROADCAST。
2.使用广播地址 255.255.255.255。
3.设置广播端口号,向局域网广播消息。

接收方:
1.将套接字绑定到广播端口。
2.监听数据到来,处理接收的广播消息。

注意:广播通信只能使用 UDP 协议,区别在于目标 IP 使用广播地址 255.255.255.255。

二,setsockopt()函数详解

setsockopt和getsockopt用于对套接字进行配置,常用于开启广播功能。

#include <sys/types.h>
#include <sys/socket.h>int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);

sock:套接字描述符。

level:选项所在协议层(如 SOL_SOCKET、IPPROTO_IP、IPPROTO_TCP)。

optname:选项名称(常见如 SO_BROADCAST)。

optval:选项值。

optlen:选项长度。

常见选项:

INADDR_ANY (0.0.0.0):表示绑定本机所有网卡地址。

INADDR_BROADCAST (255.255.255.255):广播地址,消息只在当前局域网有效。

三,粘包问题

1.什么是粘包?

在 TCP 通信中,发送方发送的多个小数据包可能会被合并到一起,接收方从缓冲区读取时无法分辨消息边界,这就是 粘包。

注意:UDP 不会发生粘包问题,因为它以报文为单位,每次 recv 只能读取一个完整 UDP 包。

2.粘包产生原因

1.发送方为了提高效率,等待缓冲区满再发送。

2.TCP 协议中的 Nagle 算法 会将多个小包合并成大包。

3.接收方处理不及时,导致多个包堆积在缓冲区中一起被读出。

3.解决办法

自定义报文格式:
使用 包头 + 数据长度 + 数据内容 的格式来传输。

包头:标识包的起始位置。
长度:告诉接收方应该读取多少字节。
包尾:标识包的结束。

示例:

[包头][数据长度][数据内容][包尾]

接收时:

先读取包头,判断一个数据包的开始。根据数据长度读取完整数据。处理完后继续读取下一个包。

4.UDP广播示例代码

发送端(send.c)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <unistd.h>int main() {int sock;struct sockaddr_in broadcastAddr;char *msg = "Hello, this is a UDP broadcast!";int broadcastPermission = 1;// 创建 UDP 套接字sock = socket(AF_INET, SOCK_DGRAM, 0);if (sock < 0) {perror("socket failed");exit(1);}// 设置套接字支持广播setsockopt(sock, SOL_SOCKET, SO_BROADCAST,&broadcastPermission, sizeof(broadcastPermission));// 设置广播地址memset(&broadcastAddr, 0, sizeof(broadcastAddr));broadcastAddr.sin_family = AF_INET;broadcastAddr.sin_port = htons(8888);broadcastAddr.sin_addr.s_addr = inet_addr("255.255.255.255");// 发送广播消息while (1) {sendto(sock, msg, strlen(msg), 0,(struct sockaddr *)&broadcastAddr, sizeof(broadcastAddr));printf("Broadcast message sent: %s\n", msg);sleep(2);}close(sock);return 0;
}

接收端(receive.c)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <unistd.h>#define BUF_SIZE 1024int main() {int sock;struct sockaddr_in recvAddr;char buffer[BUF_SIZE];socklen_t addr_len = sizeof(recvAddr);// 创建 UDP 套接字sock = socket(AF_INET, SOCK_DGRAM, 0);if (sock < 0) {perror("socket failed");exit(1);}// 绑定端口memset(&recvAddr, 0, sizeof(recvAddr));recvAddr.sin_family = AF_INET;recvAddr.sin_port = htons(8888);recvAddr.sin_addr.s_addr = htonl(INADDR_ANY);if (bind(sock, (struct sockaddr *)&recvAddr, sizeof(recvAddr)) < 0) {perror("bind failed");exit(1);}// 循环接收广播while (1) {int recvLen = recvfrom(sock, buffer, BUF_SIZE, 0,(struct sockaddr *)&recvAddr, &addr_len);buffer[recvLen] = '\0';printf("Received broadcast: %s\n", buffer);}close(sock);return 0;
}

运行结果:

五,总结

1.DP 广播适合局域网内的点对多通信,简单高效。

2.使用 setsockopt() 配置 SO_BROADCAST,通过广播地址 255.255.255.255 实现广播。

3.TCP 粘包问题在通信中较常见,可以通过自定义报文格式来解决。

4.UDP 由于以报文为单位,不会产生粘包问题。

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

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

相关文章

教育领域大模型生成题目安全研究报告

教育领域大模型生成题目安全研究报告 一、研究背景与意义 随着大语言模型&#xff08;LLM&#xff09;在教育领域的深度应用&#xff0c;自动生成题目已成为提升教学效率、实现个性化教学的关键技术手段&#xff0c;广泛应用于课堂练习、作业布置、考试命题等场景。然而&…

Android安卓项目调试之Gradle 与 Gradle Wrapper的概念以及常用gradle命令深度详解-优雅草卓伊凡

Android安卓项目调试之Gradle 与 Gradle Wrapper的概念以及常用gradle命令深度详解-优雅草卓伊凡好的&#xff0c;我们来详细梳理一下 Android 开发中 Gradle 的常用配置和调试命令。这对于每一位 Android 开发者来说都是必须掌握的核心技能。第一部分&#xff1a;Gradle 与 Gr…

Maven入门_简介、安装与配置

ZZHow(ZZhow1024) 参考课程&#xff1a; 【尚硅谷新版Maven教程】 [https://www.bilibili.com/video/BV1JN411G7gX] 一、Maven简介 02_依赖管理工具 解决 jar 包的规模问题解决 jar 包的来源问题解决 jar 包的导入问题解决 jar 包之间的依赖 03_构建工具 我们没有注意过…

Spark(1):不依赖Hadoop搭建Spark环境

不依赖Hadoop搭建Spark环境0 概述1 单机安装Spark1.1 下载Spark预编译包1.2 解压和设置1.3 配置环境变量1.4 验证安装2 Spark运行模式2.1 Local模式&#xff08;本地模式&#xff09;2.1.1 Spark Shell2.1.1.1 Python版的Shell2.1.1.2 Scala版的Shell2.1.2 提交独立的Spark应用…

【ThreeJs】【自带依赖】Three.js 自带依赖指南

&#x1f6e0;️ Three.js 辅助库生态手册 定位&#xff1a;覆盖 90% 开发场景的工具选型实操指南&#xff0c;区分「入门必备」和「进阶扩展」。 适用人群&#xff1a;Three.js 新手&#xff08;≥ r132 版本&#xff09;、需要规范开发流程的团队。 1. 控制器&#xff08;Co…

Mac电脑上如何打印出字体图标

背景 我今天打开了一个之前开发的APP&#xff0c;看到项目中用到了字体图标&#xff0c;发现有个“面条”图标用错了&#xff0c;想着修改一下吧。然后用输入法打出”面条“&#xff0c;在输入法的弹窗中就一直往下找&#xff0c;发现并没有出现图标。 想着打出”面条图标“也没…

当AI遇上数据库:Text2Sql.Net如何让“说人话查数据“成为现实

一句话概括&#xff1a;还在为写复杂SQL而头疼&#xff1f;Text2Sql.Net让你用自然语言就能查数据库&#xff0c;堪称程序员的"数据库翻译官"&#xff01; &#x1f3af; 引言&#xff1a;从"SQL地狱"到"自然语言天堂" 想象一下这样的场景&…

整体设计 之 绪 思维导图引擎 之 引 认知系统 之8 之 序 认知元架构 之4 统筹:范畴/分类/目录/条目 之2 (豆包助手 之6)

问题Q68、我们现在仅仅分析了 认知演进 的 “进”的问题&#xff0c;通过层次结构 和 统筹 的同构约束 给出了 不同对象及其对应的操作和约束。 --这句话 你能完全理解吗&#xff08;这意味着 完整的程序细节设计&#xff09;。 还没有分析的还有 “演” 以及组合词 “演进” -…

开始 ComfyUI 的 AI 绘图之旅-Qwen-Image-Edit(十二)

文章标题一、Qwen-Image-Edit1.ComfyOrg Qwen-Image-Edit 直播回放2.Qwen-Image-Edit ComfyUI 原生工作流示例2.1 工作流文件2.2 模型下载3.3 按步骤完成工作流一、Qwen-Image-Edit Qwen-Image-Edit 是 Qwen-Image 的图像编辑版本&#xff0c;基于20B模型进一步训练&#xff0c…

机械制造专属ERP:降本增效与数字转型的关键

转型升级压力下&#xff0c;ERP系统是机械企业破局的得力助手。本文深入解析ERP的核心功能、选型要点与实施价值&#xff0c;助您精准选型&#xff0c;赋能智能制造&#xff0c;全面提升竞争力。在数字化浪潮席卷之下&#xff0c;机械制造企业正面临提质、增效、降本的关键转型…

npm / yarn / pnpm 包管理器对比与最佳实践(含国内镜像源配置与缓存优化)

这篇不是“谁更快”的玄学讨论,而是把团队能落地的做法一次说清:如何选型、如何统一版本、如何把镜像与缓存配好、如何在 CI 和 Monorepo 下稳住“可重复构建”。 一、结论先说在前 单仓库 / 以稳定为先:直接用 npm(配合 npm ci) 足够,维护成本低,生态一等一,Node 16.1…

Python项目全面打包指南:从EXE到绿色软件包

📦 Python项目全面打包指南:从EXE到绿色软件包 文章目录 📦 Python项目全面打包指南:从EXE到绿色软件包 1 打包基础概念与工具选型 1.1 核心打包概念 1.2 工具对比与选型 2 项目环境准备与依赖管理 2.1 创建和管理虚拟环境 2.2 依赖管理最佳实践 2.3 依赖导出与规范文件处…

JAVA:Spring Boot 集成 FFmpeg 实现多媒体处理

1、简述 在现代 Web 应用中,音视频处理需求越来越常见,例如:视频转码、截图、音频提取、格式转换等。FFmpeg 是一个功能极其强大的开源音视频处理工具,可以帮助我们高效完成这些任务。本文将介绍如何在 Spring Boot 项目中集成 FFmpeg,并实现一些常见的应用场景。 2、为什…

推荐一款智能三防手机:IP68+天玑6300+PoC对讲+夜视

在户外探险、工业巡检及应急通信等专业领域&#xff0c;传统智能手机往往难以应对复杂苛刻的环境挑战。智能三防手机凭借其坚固的机身、专业的防护能力及定制化功能&#xff0c;成为众多行业用户的可靠工具。本文将深入解析一款集IP68防护、天玑6300处理器、PoC公网对讲及夜视等…

ego(4)---检测B样条轨迹的障碍物进入点与退出点

障碍物进出点检测的作用在经过 B 样条的控制点采样后&#xff0c;接下来是绕障的环节&#xff0c;绕障使用的是 Astar &#xff0c;但在使用 Astar 之前&#xff0c;需要进行障碍物进出点的检测与标记。通俗点讲&#xff0c;这部分的作用就是为 Astar 绕障碍做前置准备。检测进…

在springboot中使用mock做controller层单元测试,请求示例包括GET(带参数)、POST(带请求头)、下载文件、上传文件等

以下是SpringBoot中使用MockMvc进行Controller层单元测试的完整示例,涵盖GET带参数、POST带请求头、文件下载和文件上传等场景: GET请求测试(带路径参数) @Test void testGetWithPathParam() throws Exception {mockMvc.perform(MockMvcRequestBuilders.

领码SPARK融合平台 · TS × Java 双向契约:构建稳定可演进的全栈系统——落地篇|配置即契约,守卫即护栏

系列总引 本系列致力于构建可复制、可演进的低代码平台类型治理闭环&#xff0c;从原理到落地、AI 驱动到性能治理。落地篇聚焦工程实践&#xff0c;通过“契约单源 → 自动生成 → 前后端守卫协同 → CI/CD 管控”的完整流水线&#xff0c;将原理篇的类型方法论落到生产环境中…

Gradio全解11——Streaming:流式传输的视频应用(8)——Gemini Live API:实时音视频连接

Gradio全解11——Streaming&#xff1a;流式传输的视频应用&#xff08;8&#xff09;——Gemini Live API&#xff1a;实时音视频连接11.8 Gemini Live API&#xff1a;实时音视频连接11.8.1 Live API——入门1. Live API技术与功能介绍2. 选择音频生成架构和实施方案3. 异步发…

事务学习总结

目录 事务四大特性 事务四种隔离级别 事务七种传播行为 事务四大特性 原子性Atomicity 要么同时成功&#xff0c;要么同时失败。事务一旦发生失败就会回滚到原来最初的样子&#xff0c;仿佛没有发生过一样 一致性Consistency 事务处理前后&#xff0c;数据完整性要保持一…

JavaWeb--day4--WebHttp协议Tomcat

&#xff08;以下内容全部来自上述课程及课件&#xff09; 这里maven我学过了&#xff0c;可见&#xff1a;Maven项目管理–基础篇&#xff0c;所以跳过 SpringBootWeb 1. 需求 需求&#xff1a;基于SpringBoot的方式开发一个web应用&#xff0c;浏览器发起请求/hello后&…