【Airplay_BCT】Bonjour API架构
Bonjour API 架构
OS X 和 iOS 为 Bonjour 服务应用程序提供了多层应用程序编程接口 (API): Foundation 框架中的 NSNetService 和 NSNetServiceBrowser 类; CFNetServices,Core Services 中 CFNetwork 框架的一部分; Java 的 DNS 服务发现(仅限 OS X);以及围绕 BSD 套接字构建的低级 DNS 服务发现 API。所有三个 API 集都为网络服务的发布、发现和解析提供便利。图 3-1 说明了 API 层的结构。如您所见,多播 DNS 响应程序(或其他 DNS 服务器)位于最低级别,因此您的软件不必直接与 DNS 交互。

NSNetService 和 NSNetServiceBrowser
NSNetService 和 NSNetServiceBrowser 类是 Cocoa 中基础框架的一部分,为服务发现和发布提供了面向对象的抽象。 NSNetService 对象表示 Bonjour 服务的实例,用于发布或由客户端发现的服务,而 NSNetServiceBrowser 表示用于特定类型服务的浏览器。大多数 Cocoa 程序员应该会发现这些类足以满足他们的需要。如果您需要更详细的控制,您可以使用来自 Cocoa 应用程序的 DNS 服务发现 API。
NSNetService 和 NSNetServiceBrowser 被调度在默认的 NSRunLoop 对象上,以异步方式执行发布、发现和解析。 NSNetService 和 NSNetServiceBrowser 对象返回的所有结果都由委托对象处理。这些对象必须与一个运行循环相关联才能运行,但它不必是默认的。
CFNet服务
Core Services 框架中声明的 CFNetServices API 提供了 Core Foundation 风格的类型和函数,用于管理服务和服务发现。 CFNetServices 定义了三种 Core Foundation 对象类型,CFNetService、CFNetServiceBrowser 和 CFNetServiceMonitor。 CFNetService 是服务实例的抽象表示,可用于发布或使用。关联函数为发布和解析服务提供支持。 CFNetServiceBrowser 表示特定域中特定类型服务的浏览器。通常只有在 OS X 或 iOS 的核心基础层编写代码时才应使用此 API。
CFNetService 和 CFNetServiceBrowser 对象通常在 CFRunLoops 中提供服务。为检索结果,应用程序实施回调函数来处理事件,例如新服务出现或消失、正在解析的实例以及发生的错误。与 NSNetService 和 NSNetServiceBrowser 不同,CFNetServices 类型不需要运行循环,并且可以在需要此行为时同步运行。但是,使用这些函数的同步模式是不好的做法。
DNS 服务发现
在 /usr/include/dns_sd.h 中声明的 DNS 服务发现 API 为 Bonjour 服务提供低级 BSD 套接字通信。 DNS 服务发现充当您的软件和多播 DNS 响应程序或 DNS 服务器之间的中间层。它为您管理多播 DNS 响应程序,让您根据服务和服务浏览器而不是 DNS 资源记录来编写程序。
因为 DNS 服务发现 API 是 Darwin 开源项目的一部分,所以您应该在编写跨平台代码(适用于 iOS 和 OS X 以外的平台)或需要使用更高版本中不可用的低级功能时使用它级 API,例如 NSNetService。
如果为 Windows、Linux 或 FreeBSD 开发 Bonjour 服务应用程序,DNS 服务发现也是应该使用的 API。
## Bonjour Operations
本章描述了作为三个网络服务 API 层和 API 层本身基础的服务发布、浏览和解析的 Bonjour 操作。如果你想编写一个发布或发现网络服务的应用程序或工具,你应该阅读本章。
架构概述
Bonjour 中的网络服务架构包括一个易于使用的机制,用于发布、发现和使用基于 IP 的服务。 Bonjour 支持三个基本操作,每个操作都是零配置网络服务的必要部分:
- 出版物(为服务做广告)
- 发现(浏览可用服务)
- 解析(将服务实例名称翻译成地址和端口号以供使用)
## 出版物
要发布服务,应用程序或设备必须通过高级 API 或直接与响应器 (mDNSResponder) 通信,向多播 DNS 响应器注册该服务。 Bonjour 还支持使用动态 DNS 更新在传统 DNS 服务器上存储记录。
注册服务时,会创建三个相关的 DNS 记录:服务 (SRV) 记录、指针 (PTR) 记录和文本 (TXT) 记录。 TXT 记录包含解析或使用服务所需的附加数据,尽管它通常也是空的。
服务记录
SRV 记录将服务实例的名称映射到客户端实际使用该服务所需的信息。然后,客户端将服务实例名称存储为访问服务的持久方式,并在需要连接时对主机名和端口号执行 DNS 查询。这种额外的间接级别提供了两个重要的特性。首先,该服务由人类可读的名称而不是域名和端口号来标识。其次,即使服务的端口号、IP 地址或主机名发生变化,只要服务名称保持不变,客户端也可以访问该服务。
SRV 记录包含两条信息来标识服务:
- 主机名
- 端口名
主机名是当前可以找到该服务的域名。给出主机名而不是单个 IP 地址的原因是它可能是具有多个 IP 地址的多宿主主机,或者它可能具有 IPv6 地址和 IPv4 地址,等等。通过名称识别主机可以优雅地处理所有这些情况。
端口号标识服务的 UDP 或 TCP 端口。
SRV 记录根据以下约定命名:
<Instance Name>.<Service Type>.<Domain>
<实例名称>.<服务类型>.<域>
,服务实例的名称,可以是任何 UTF-8 编码的 Unicode 字符串,并且旨在供人类阅读。
是一个标准的 IP 协议名称,前面有一个下划线,后面是主机到主机的传输协议(TCP 或 UDP),前面也有一个下划线。例如,在 UDP 上运行的普通 FTP 服务将具有 _tftp._udp 服务类型,而在 TCP 上运行的 IPP 打印服务将在 _ipp._tcp 服务类型下注册。官方协议名称列表由 IANA 维护;有关详细信息,请参阅域命名约定。
是一个标准的 DNS 域。这可能是特定域,例如 apple.com.,或通用后缀 local。对于只能在本地链接上访问的服务。
以下是在 TCP 端口 515 上运行的名为 PrintsAlot 的后台打印程序的 SRV 记录示例(采用标准 DNS 记录格式):PrintsAlot._printer._tcp.local。 120 IN SRV 0 0 515 blackhawk.local。
该记录将在名为 blackhawk.local 的打印机的多播 DNS 响应器上创建。在本地链接上。初始 120 表示用于缓存的生存时间 (TTL) 值。两个零是权重和优先级值,在传统 DNS 中用于在与给定名称匹配的多个记录之间进行选择;对于多播 DNS,这些值将被忽略。
指针记录
PTR 记录通过将服务类型映射到该类型服务的特定实例的名称列表来启用服务发现。此记录添加了另一层间接寻址,因此只需查找标有服务类型的 PTR 记录即可找到服务。
该记录仅包含一条信息,即服务实例的名称(与 SRV 记录的名称相同)。 PTR 记录相应地命名为 SRV 记录,但没有实例名称:<Service Type>.<Domain>
以下是名为 PrintsAlot 的后台打印程序的 PTR 记录示例_printer._tcp.local。 28800 PTR PrintsAlot._printer._tcp.local。
同样,28800 是生存时间 (TTL) 值,以秒为单位。
文本记录
TXT 记录与对应的 SRV 记录同名,可以包含少量关于服务实例的附加信息,通常最多不超过 100-200 字节。此记录也可能为空。例如,网络游戏可以通告多人游戏中使用的地图名称,聊天程序可以通告用户的可用性(例如,闲置、离开或可用)。如果需要传输的数据量较大,主机应与客户端建立连接,直接发送数据。
从历史上看,此记录已用于在同一 IP 地址的同一端口上运行的多个服务,例如在同一打印服务器上运行的多个打印队列。在这种情况下,TXT 记录中的附加信息可用于识别预期的打印队列,如本例所示:
这种做法是必要的,因为服务类型历来与众所周知的端口相关联。鼓励新的 Bonjour 协议的设计者在不同的动态分配的端口号上运行他们服务的每个实例,而不是试图在同一个众所周知的端口号上运行它们并使用额外的信息来指定客户端正在尝试交谈的实例到。
TXT 记录中数据的性质和格式是特定于每种服务类型的,因此每种新服务类型还需要为其关联的 TXT 记录(如果有)定义数据格式,并将此格式发布为协议规范。
例子
举一个具体的例子,假设有一个通过本地网络共享音乐的设备——支持 IP 的自动点唱机。假设它的传输协议是 TCP,它的应用协议名为 music。当有人将设备插入以太网集线器时,会发生许多事情,如图 4-1 所示。

在步骤 1 中,设备从 IPv4 链路本地范围 169.254.0.0 中随机选择子网掩码为 255.255.0.0 的链路本地 IP 地址 169.254.150.84,并将其公布到网络中。因为没有设备响应通知,所以设备将地址作为自己的地址。在第 2 步中,它启动自己的多播 DNS 响应程序,请求主机名 eds-musicbox.local.,验证其可用性,并将该名称作为自己的名称。接下来,在步骤 3 中,设备在 TCP 端口 1010 上启动音乐共享服务。最后,在步骤 4 中,它在本地以名称 Ed’s Party Mix 发布类型为 _music._tcp 的服务。域,首先确保不存在同名服务。这将创建两个记录:
- 名为 Ed’s Party Mix._music._tcp.local 的 SRV 记录。指向 eds-musicbox.local。在 TCP 端口 1010 上
- 名为 _music._tcp.local 的 PTR 记录。指向 Ed 的 Party Mix._music._tcp.local。服务。
注意:发布服务时,如果域名或服务名称不可用,没有接口的设备应选择一个新名称。遇到这种情况的应用软件应该呈现一个用户界面,通知用户该名称不可用,并允许用户选择一个不同的名称。
发现
服务发现利用在服务发布期间注册的 DNS 记录来查找特定类型服务的所有命名实例。为此,应用程序通常通过更高级别的 API 查询与服务类型(例如 _http._tcp)匹配的 PTR 记录。在每台设备上运行的多播 DNS 响应程序返回带有服务实例名称的 PTR 记录。

图 4-2 说明了浏览音乐共享服务的客户端应用程序。在第 1 步中,客户端应用程序发出对本地 _music._tcp 类型服务的查询。域到标准多播地址 224.0.0.251。网络上的每个多播 DNS 响应程序都会听到请求,但只有音乐共享设备会使用 PTR 记录进行响应(第 2 步)。生成的 PTR 记录包含服务实例名称 Ed’s Party Mix._music._tcp.local。在这种情况下。然后,客户端应用程序可以从 PTR 记录中提取服务实例名称,并将其添加到屏幕上的音乐服务器列表中。
解析
服务发现通常只偶尔发生一次——例如,当用户第一次选择打印机时。此操作保存服务实例名称,即任何给定服务实例的预期稳定标识符。端口号、IP 地址,甚至主机名每天都在变化,但用户不需要每次都重新选择打印机。因此,从服务名称到套接字信息的解析直到服务被实际使用时才会发生。
为了解析服务,应用程序使用服务名称执行 SRV 记录的 DNS 查找。多播 DNS 响应器使用包含当前信息的 SRV 记录进行响应。
图 4-3 说明了音乐共享示例中的服务解析。解析过程从向多播地址 224.0.0.251 请求 Ed’s Party Mix._music._tcp.local 的 DNS 查询开始。 SRV 记录(步骤 1)。在第 2 步中,此查询返回服务的主机名和端口号 (eds-musicbox.local., 1010)。在第 3 步中,客户端发出 IP 地址的多播请求。在第 4 步中,此请求解析为 IP 地址 169.254.150.84。然后客户端可以使用 IP 地址和端口号连接到服务。每次使用服务时都会发生此过程,因此总能找到服务的最新地址和端口号。

相关文章:
【Airplay_BCT】Bonjour API架构
Bonjour API 架构 OS X 和 iOS 为 Bonjour 服务应用程序提供了多层应用程序编程接口 (API): Foundation 框架中的 NSNetService 和 NSNetServiceBrowser 类; CFNetServices,Core Services 中 CFNetwork 框架的一部分; Java 的 DN…...
为什么sleeping的会话会造成阻塞(2)
背景客户反馈系统突然从11:10开始运行非常缓慢,在SQL专家云中看到大量的产生阻塞的活动会话,KILL掉阻塞的源头马上又出现新的源头,实在没有办法只能重启应用程序断开所有数据库连接才解决,请我们协助分析根本的原因。现象登录SQL专…...
从矩阵中提取对角线元素;将一维数组转换为对角线矩阵:np.diag()函数
【小白从小学Python、C、Java】【计算机等级考试500强双证书】【Python-数据分析】从矩阵中提取对角线元素将一维数组转换为对角线矩阵np.diag()函数选择题下列说法错误的是?import numpy as npmyarray1 np.array([1,2,3])print("【显示】myarray1")print(myarray1…...
JavaSE学习day7_02 封装和构造方法
4. 封装 面向对象的三大特征: 封装、继承、多态 封装:对象代表什么,就得封装对应的数据,并提供数据对应的行为。 比如人画圆:”画“这个行为应该封装在圆这个类,为什么?因为”画“圆要知道圆…...
2022年FIT2CLOUD飞致云开源成绩单
2023年2月15日,中国领先的开源软件公司FIT2CLOUD飞致云发布《2022年开源成绩单》,盘点公司2022年全年在开源软件产品与社区运营方面的表现。目前,飞致云旗下的核心开源软件组合包括JumpServer开源堡垒机、DataEase开源数据可视化分析平台、Me…...
【Python】asyncio使用注意事项
目录协程的定义协程的运行多个协程运行关于loop.close()回调事件循环协程的定义 需要使用 async def 语句 协程可以做哪些事: 1、等待一个future结果 2、等待另一个协程(产生一个结果或引发一个异常) 3、产生一个结果给正在等它的协程 4、引发一个异常给正在等它的协程 …...
成都链安受邀参加第五届CCF中国区块链技术大会
2月10-12日,由中国计算机学会主办的,2023年国内首场大型区块链学术会议—第五届CCF中国区块链技术大会在无锡市成功举办,成都链安作为区块链安全头部企业受邀参加此次大会。大会上,成都链安创始人&CTO郭文生教授与锡东新城商务…...
验证码识别--封装版
前面我们说过了数字英文的验证码识别操作,本章我们对其进行完善一下,结合selenium来实际操作操作。import osimport timedef coding_path(path):Base_Path os.path.abspath(os.path.dirname(os.path.abspath(__file__)) /..)Base_image os.path.join(…...
创建Wails项目
项目生成 现在 CLI 已安装,您可以使用 wails init 命令生成一个新项目。 选择您最喜欢的框架: SvelteReactVuePreactLitVanilla 使用 JavaScript 生成一个 Vue 项目: wails init -n myproject -t vue如果您更愿意使用 TypeScript: wails init -…...
深度解析UG二次开发装配的部件事件、部件原型和部件实例
做UG二次开发快一年了,每次遇到装配的问题涉及到部件事件、部件原型和部件实例还是一头雾水,什么是实例,什么是原型这些专业术语等等。 针对这个问题,今天专门写了一篇特辑,结合装配实例深度剖析装配过程中的的所有参数…...
Linux安装elasticsearch-head
elasticsearch-head 是一款专门针对于 elasticsearch 的客户端工具,用来展示数据。 elasticsearch-head 是基于 JavaScript 语言编写的,可以使用 Nodejs 下的包管理器 npm 部署。 1 安装Nodejs nodejs下载地址: https://nodejs.org/en/dow…...
MySQL InnoDB表的碎片量化和整理(data free能否用来衡量碎片?)
网络上有很多MySQL表碎片整理的问题,大多数是通过demo一个表然后参考data free来进行碎片整理,这种方式对myisam引擎或者其他引擎可能有效(本人没有做详细的测试).对Innodb引擎是不是准确的,或者data free是不是可以参…...
Leetcode-每日一题1250. 检查「好数组」(裴蜀定理)
题目链接:https://leetcode.cn/problems/check-if-it-is-a-good-array/description/ 思路 方法:数论 题目意思很简单,让你在数组 nums中选取一些子集,可以不连续,子集中的每个数再乘以任意的数的和是否为1ÿ…...
OpenStack手动分布式部署环境准备【Queens版】
目录 1.基础环境准备(两个节点都需要部署) 1.1关闭防火墙 1.2关闭selinux 1.3修改主机名 1.4安装ntp时间服务器 1.5修改域名解析 1.6添加yum源 2.数据库安装配置 2.1安装数据库 2.2修改数据库 2.3重启数据库 2.4初始化数据库 3.安装RabbitMq…...
Web自动化测试——selenium的使用
⭐️前言⭐️ 本篇文章就进入了自动化测试的章节了,如果作为一名测试开发人员,非常需要掌握自动化测试的能力,因为它不仅能减少人力的消耗,还能提升测试的效率。 🍉欢迎点赞 👍 收藏 ⭐留言评论 …...
虚拟交换单元技术
支持VSU(Virtual Switch Unit)即虚拟交换单元技术。通过聚合链路连接,将多台物理设备虚拟为一台逻辑上统一的设备,使其能够实现统一的运行,利用单一IP 地址、单一Telnet 进程、单一命令行接口(CLI)、自动版本检查、自动…...
【STM32笔记】HAL库外部定时器、系统定时器阻塞、非阻塞延时
【STM32笔记】HAL库外部定时器、系统定时器阻塞、非阻塞延时 外部定时器 采用定时器做延时使用时 需要计算好分频和计数 另外还要配置为不进行自动重载 对于50MHz的工作频率 分频为50-1也就是50M/501M 一次计数为1us 分频为50000-1也就是1k 一次计数为1ms 我配置的是TIM6 只…...
[Springboot 单元测试笔记] - Mock 和 spy的使用
Springboot单元测试 - 依赖类mock测试 通常单元测试中,我们会隔离依赖对于测试类的影响,也就是假设所有依赖的一定会输出理想结果,在测试中可以通过Mock方法来确保输出结果,这也就引入另一个测试框架Mockito。 Mockito框架的作用…...
互联网新时代要来了(二)什么是AIGC?
什么是AIGC? 最近,又火了一个词“**AIGC”**2022年被称为是AIGC元年。那么我们敬请期待,AIGC为我们迎接人工智能的下一个时代。 TIPS:内容来自百度百科、知乎、腾讯、《AIGC白皮书》等网页 什么是AIGC?1.什么是AIGC?…...
75V的TVS二极管有哪些型号?常用的
瞬态抑制TVS二极管工作峰值反向电压最低3.3V,最高可达513V,甚至更高。很多电子工程师都知道,TVS二极管在实际应用选型过程中,第一步要确认的就是其工作峰值反向电压。2023年春节已过,东沃电子正月初八就开工了…...
Docker 运行 Kafka 带 SASL 认证教程
Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...
【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...
2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...
如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
华为OD最新机试真题-数组组成的最小数字-OD统一考试(B卷)
题目描述 给定一个整型数组,请从该数组中选择3个元素 组成最小数字并输出 (如果数组长度小于3,则选择数组中所有元素来组成最小数字)。 输入描述 行用半角逗号分割的字符串记录的整型数组,0<数组长度<= 100,0<整数的取值范围<= 10000。 输出描述 由3个元素组成…...
Linux中《基础IO》详细介绍
目录 理解"文件"狭义理解广义理解文件操作的归类认知系统角度文件类别 回顾C文件接口打开文件写文件读文件稍作修改,实现简单cat命令 输出信息到显示器,你有哪些方法stdin & stdout & stderr打开文件的方式 系统⽂件I/O⼀种传递标志位…...
