Bonjour:按名称搜索服务

格罗德里格斯

我有一个应用程序需要搜索和解析一个预先知道名称的 Bonjour 广告服务。我发现的大多数与服务发现相关的 Bonjour 示例的结构或多或少是这样的:

  1. 调用browse以检测给定类型的所有服务(例如,这可能是_http._tcp
  2. 对于找到的每个服务,serviceFound都会调用。服务名称在此处报告
  3. 调用resolve找到的每个服务
  4. 对于每个解决的服务,serviceResolved称为

Bonjour 是否可以跳过“发现”阶段,因为我事先知道要解析的服务的名称?我可以只检测和解析具有已知名称的服务吗?

亚历山大·芬约

1-答案

是的,如果您已经知道服务的名称,则可以从第 3 步开始。这是因为此步骤是通过 DNS 查找 SRV 记录来执行的,其中 SRV 记录具有发送到众所周知的多播地址的服务名称因此,进行此调用不需要先前的信息,并且 mDNS 响应者必须是无状态的,因为底层 DNS 协议是无状态的(每个响应都绑定到一个唯一的请求 - 在多个请求之间没有保持状态)。

2- 示例

这是我刚刚用 Swift 编写的一个示例,它通过了在我的 iPad 上运行的测试,以找到在我的 Mac Mini 上运行的服务。因此,我们假设域为local,服务类型,服务_http._tcp名称为myservice,运行在主机 Mac-mini-de-Alexandre.local 上并侦听 TCP 端口 8080。

为了跟踪有关服务的信息,例如其主机名和 TCP 端口,我们定义了一个实现 NetServiceDelegate 协议的类:

class MyNetServiceDelegate : NSObject, NetServiceDelegate {
     public func netServiceDidResolveAddress(_ sender: NetService) {
        print(sender.hostName!, sender.port)
    }
}

这个新类将用于实例化 NetService 实例的委托。

因此,我们创建了一个对应于我们已经知道的服务的 NetService 实例,我们将其长期存储在某个主类的静态常量属性中:

static let ns = NetService(domain: "local.", type: "_http._tcp.", name: "myservice")

它被长期存储,因为在我们找到我们的服务之前它不能被释放。

请注意,类 NetService 中的委托属性被声明为 unowned (unsafe)因此,我们还需要创建对委托实例的引用:

static let ns_deleg = MyNetServiceDelegate()

当我们要解析服务时,我们可以这样写:

ns.delegate = ns_deleg
ns.resolve(withTimeout: TimeInterval(10))

resolve()如果找到服务,委托实例将在稍后调用(是一种非阻塞方法),在这种情况下,它将打印主机名和端口。

这是我在 Xcode 输出窗口中得到的输出:

Mac-mini-de-Alexandre.local. 8080

最后,请注意,由于无主引用,编写以下代码将是错误的(委托实例将很快被释放):

// bad code -- do not write that -- only here to show a common mistake
ns.delegate = MyNetServiceDelegate()
ns.resolve(withTimeout: TimeInterval(10))

3- 帮助调试的技巧

这里有一个调试这种 mDNS 解析的小技巧:在 Unix shell(例如 macOS)上,只需运行以下行:

dig -p 5353 @224.0.0.251 myservice._http._tcp.local. SRV +short

如果名为 myservice 的 http 服务正在运行,您将获得主机名和端口。通过我的示例,您将获得以下信息:

0 0 8080 Mac-mini-de-Alexandre.local.

因此,在尝试使用我在此处编写的 Swift 代码之前,只需检查您的服务是否已使用此 shell 命令正确宣布。

最后,请注意,这个基于 dig 的命令仅在每个 IPv4 网络接口上进行一个 IPv4 mDNS 查询,但是使用 Apple Bonjour API,会自动完成两组 mDNS 请求:一组使用 IPv4 到每个网络接口上的多播目的地 224.0.0.251支持 IPv4,另一个使用 IPv6 到支持 IPv6 的每个接口上的多播目的地 ff02::fb。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Android SQLite按名称搜索

来自分类Dev

mysqli-按名称搜索

来自分类Dev

MVC:按视频名称搜索

来自分类Dev

按 JSON 字段搜索名称

来自分类Dev

如何仅按名称搜索点子包?

来自分类Dev

按名称Perl搜索XML元素值

来自分类Dev

如何按名称搜索要点

来自分类Dev

Trip Advisor API按位置名称搜索

来自分类Dev

在Seam中按特定的Cloumn名称搜索

来自分类Dev

可以按名称搜索SKSpriteNode对象吗

来自分类Dev

图像存储在磁盘上-按名称搜索

来自分类Dev

按班级名称和文本搜索

来自分类Dev

按名称搜索本地 html 文件

来自分类Dev

按名称和 ID 搜索记录

来自分类Dev

按标签名称或资源名称搜索资源

来自分类Dev

Twitter API请求名称趋势(按名称搜索)

来自分类Dev

Autofac按名称解析依赖服务

来自分类Dev

无法在kubernetes上按服务名称访问服务

来自分类Dev

使用netbios / bonjour名称进行的nmap扫描

来自分类Dev

从IP地址检索Bonjour(Zeroconf / mDNS)名称

来自分类Dev

在magento中按名称搜索产品并获取产品ID的数组

来自分类Dev

Eclipse-按名称从资源搜索中排除文件

来自分类Dev

如何在iOS中按名称,位置搜索本地业务?

来自分类Dev

更改TStrings.Delimiter将按名称中断搜索

来自分类Dev

Powershell AD用户按名称和OU搜索

来自分类Dev

按名称搜索工作表并使用VBScript激活它

来自分类Dev

如何在iOS中按名称,位置搜索本地业务?

来自分类Dev

按类别名称搜索和查找DIV的内容

来自分类Dev

按名称搜索,不包括空格或带空格