iOS- 如何使用Apple的零配置网络协议Bonjour?

1.前言  

这段时间为了解决公司App的网络离线需求,做了个Apple推出的零配置网络协议Bonjour的Test,主要是为了解决iOS设备的IP获取,之前是可以使用socket的广播来实现,但是使用Apple推出的Bonjor相比会更加简单和稳定。希望能对大家有点帮助,如果有什么地方有error也欢迎大家指出,互相学习。

这是之前写过的一篇关于socket的blog——socket广播

iOS- 移动端Socket UDP协议广播机制的实现

2.什么是Bonjour?能做些什么?  

相信没有了解过Bonjour的朋友对这个东西会比较陌生,Bonjor如标题所言,是Apple退出的一种零配置网络协议,Bonjour可以完成的工作主要是在缺少中心服务器的情况下解决IP获取,名称解析和服务发现这三个问题。

2.1 IP获取  

在传统网络环境下,设备的IP地址通过两种方式获取,一种是静态配置,通过手工方式为设备指定一个IP地址,一种是动态配置,设备通过路由器的DHCP服务获得动态的IP地址。

在无中心服务器的网络环境下,没有中心服务器提供DHCP服务,用户手工配置IP地址也很不方便,这就需要一种新的方式来帮助设备获取IP地址,就是希望设备可以主动为自己指定一个可用的IP地址。

在IPV6环境下,IPV6协议本身就提供了设备自指定IP地址的能力,所以实现很简单,直接使用IPV6的协议支持就可以了。

在IPV4环境下,Bonjour使用了随机指定IP地址的方法,首先为设备随机指定一个属于本地网段的IP地址,然后检查该地址在本地是否有冲突,如果有冲突就随机生成另一个新的IP地址,直到找到可用IP地址为止。

2.2 名称解析  

在传统网络环境下,名称和IP地址的对应关系是通过DNS服务解析的。当一个设备需要访问一个域名,如“www.saup.com”,设备将“www.saup.com”发给DNS服务器,服务器返回该域名对应的IP地址,设备再使用返回的IP地址对目标服务器进行访问。

在没有中心服务器的网络环境中,没有DNS服务器提供域名解析服务,名称解析变成一个严重问题。针对这一问题,业界的解决方案是mDNS,中文叫“组播DNS”,在标准文档RFC6762中定义。

“组播DNS”的原理很简单,当一个设备需要解析一个名称时,如“abc.local.”,这个设备通过UDP协议向本地网络中的所有设备广播一个消息,问谁是“abc.local”,本地网络中如果有一个设备认为自己是“abc.local”,它就给出响应,说出自己的IP地址。

因为“组播DNS”基于UDP协议,采用广播消息的方式,所以不需要一个中心服务器提供DNS解析服务就可以完成本地的名称解析。

Bonjour也是基于mDNS协议的,不过Bonjour在mDNS协议上作了扩展,加强了设备响应“组播DNS”请求的能力。在Bonjour协议下,应用只需要对某个名称进行注册,就可以将响应“组播DNS”请求的工作交由底层处理。也就是说在Bonjour协议下,应用不需要侦听本地网络的“组播DNS”请求并进行响应,这些工作由底层系统完成。

为了区分全球域名和本地域名,mDNS协议使用“.local.”作为本地域名的根域名。

2.3 服务发现  

当一个提供服务的设备获取IP地址,并自我指定一个域名后,其实还是不能满足用户的需求。因为用户需要的是某种服务,如打印服务,web服务,用户并不关心这些服务对应的服务器名称和它的IP地址。

为了让用户更容易发现本地网络中的各种服务,Bonjour为设备提供了服务发现的能力。

Bonjour提供的“服务发现”能力基于一个简单直接的规定,就是提供服务的设备在按以下标准对服务进行注册:“名称.服务类型.传输协议类型.local.”,比如:“DamonWebServer._http._tcp.local.”,又比如“DummiesWebServer._http._tcp.local.”。

这样,当一个设备使用希望查找http服务的时候,Bonjour会去查找本地网络中注册过的包含"_http"的服务,然后将结果返回给用户选择。这时用户面对的是“DamonWebServer”和"DummiesWebServer",用户可以不去关心到底这两个web服务到底在那台设备上,该设备的IP地址是什么。

3.Bonjour的使用?  

Bonjour的使用主要分为两部分

3.1.Bonjour服务端注册服务  

//首先我们需要使用到iOS SDK里的NSNetService类
@property(strong,nonatomic)NSNetService*netService;
//初始化服务,指定服务的域,类型,名称和端口
   _netService = [[NSNetService alloc] initWithDomain:@"local." type:@"_http._tcp." name:@"DamonWebServer" port:5222];
//指定代理
[_netServicesetDelegate:self];
//发布注册服务
[_netService publish];
//NSNetServiceDelegate代理协议相关代理方法  按需求使用
@protocolNSNetServiceBrowserDelegate <NSObject>
@optional

/* Sent to the NSNetServiceBrowser instance‘s delegate before the instance begins a search. The delegate will not receive this message if the instance is unable to begin a search. Instead, the delegate will receive the -netServiceBrowser:didNotSearch: message.
*/
- (void)netServiceBrowserWillSearch:(NSNetServiceBrowser*)aNetServiceBrowser;

/* Sent to the NSNetServiceBrowser instance‘s delegate when the instance‘s previous running search request has stopped.
*/
- (void)netServiceBrowserDidStopSearch:(NSNetServiceBrowser*)aNetServiceBrowser;

/* Sent to the NSNetServiceBrowser instance‘s delegate when an error in searching for domains or services has occurred. The error dictionary will contain two key/value pairs representing the error domain and code (see the NSNetServicesError enumeration above for error code constants). It is possible for an error to occur after a search has been started successfully.
*/
- (void)netServiceBrowser:(NSNetServiceBrowser*)aNetServiceBrowser didNotSearch:(NSDictionary*)errorDict;

/* Sent to the NSNetServiceBrowser instance‘s delegate for each domain discovered. If there are more domains, moreComing will be YES. If for some reason handling discovered domains requires significant processing, accumulating domains until moreComing is NO and then doing the processing in bulk fashion may be desirable.
*/
- (void)netServiceBrowser:(NSNetServiceBrowser*)aNetServiceBrowser didFindDomain:(NSString*)domainString moreComing:(BOOL)moreComing;

/* Sent to the NSNetServiceBrowser instance‘s delegate for each service discovered. If there are more services, moreComing will be YES. If for some reason handling discovered services requires significant processing, accumulating services until moreComing is NO and then doing the processing in bulk fashion may be desirable.
*/
- (void)netServiceBrowser:(NSNetServiceBrowser*)aNetServiceBrowser didFindService:(NSNetService*)aNetService moreComing:(BOOL)moreComing;

/* Sent to the NSNetServiceBrowser instance‘s delegate when a previously discovered domain is no longer available.
*/
- (void)netServiceBrowser:(NSNetServiceBrowser*)aNetServiceBrowser didRemoveDomain:(NSString*)domainString moreComing:(BOOL)moreComing;

/* Sent to the NSNetServiceBrowser instance‘s delegate when a previously discovered service is no longer published.
*/
- (void)netServiceBrowser:(NSNetServiceBrowser*)aNetServiceBrowser didRemoveService:(NSNetService*)aNetService moreComing:(BOOL)moreComing;

3.2.Bonjour客户端发现本地服务  

//客户端主要使用的是iOS SDK里的NSNetServiceBrowser
@property(strong,nonatomic)NSNetServiceBrowser*serverBrowser;
@property(strong,nonatomic)NSMutableArray*servers;
//NSNetService在客户端用于解析
@property(strong,nonatomic)NSNetService*netserver;

//初始化NSNetServiceBrowser
_serverBrowser= [[NSNetServiceBrowseralloc]init];
//指定代理
_serverBrowser.delegate = self;
_servers = [NSMutableArrayarray];
//查找服务
接着使用NSNetServiceBrowser实例的searchForServicesOfType方法查找服务,方法中可以指定需要查找的服务类型和查找的域
[_serverBrowsersearchForServicesOfType:@"_http._tcp."inDomain:@"local."];

NSNetServiceBrowserDelegate代理协议相关代理方法

注:客户端可以通过NSNetService解析服务,解析成功后,可以获得通讯的数据细节,如:IP地址、端口等信息。 

-//下面是几个常用的代理方法

//即将解析服务,
- (void)netServiceWillResolve:(NSNetService *)netService {

    NSLog(@"netServiceWillResolve");

}
//解析服务成功
- (void)netServiceDidResolveAddress:(NSNetService *)netService {

    NSLog(@"service ip:%@,------port:%d",netService.addresses,netService.port);

}
 //解析服务失败,解析出错
- (void)netService:(NSNetService *)netService didNotResolve:(NSDictionary *)errorDict {

    NSLog(@"didNotResolve: %@",errorDict);

}  

//已发现服务
- (void)netServiceBrowser:(NSNetServiceBrowser *)netServiceBrowser didFindService:(NSNetService *)netService moreComing:(BOOL)moreServicesComing
{

    NSLog(@"didFindService");
    _netserver = netService;
    _netserver.delegate = self;
    //设置解析超时时间
    [_netserverresolveWithTimeout:5.0];

}

作者: 清澈Saup
出处:http://www.cnblogs.com/qingche/
本文版权归作者和博客园共有,欢迎转载,但必须保留此段声明,且在文章页面明显位置给出原文连接。

时间: 2024-10-18 00:20:19

iOS- 如何使用Apple的零配置网络协议Bonjour?的相关文章

6.4 配置网络协议

6.4  配置网络协议 在客户端连接到数据库引擎之前,数据库引擎必须启用网络协议.SQL Server 数据库引擎可同时启用多种网络协议为请求服务,客户端则使用单个协议连接到数据库引擎. 可以直接在右键菜单中启用或禁用某个网络协议.还可以在"属性"窗口进行详细配置,修改过的属性在重新启动该实例后生效. 6.4.1  配置Shared Memory协议 Shared Memory 协议的配置只有一个"已启用"选项. 6.4.2  配置 Named Pipes 协议 如

6.3 配置网络协议的安全性

6.3  配置网络协议的安全性 如果是 64 位操作系统环境,在 SSCM 控制台窗口展开根节点后,可以看到2个与网络配置相关的节点. ◆ SQL Server 网络配置(32位) 这个节点将列出这台计算机上所安装的所有 32 位的SQL Server 实例. ◆ SQL Server 网络配置 这个节点将列出这台计算机上所安装的所有 64 位的SQL Server 实例. 如果这台计算机是32位操作系统,由于只能安装32位的 SQL Server 实例,所以只会显示一个"SQL Server

ESP8266零配置网络

概念: Zeroconf (Zero-configuration networking 零配置联网) 功能: 1 自动配置IP地址  (Link-local 地址), 2 自动配置并解析域名,这项技术被称为 mDNS (Multicast Domain Name Service,多点发送域名服务) 3 在网络传播和接收自己与其他设备所能提供的服务.DNS-SD(DNS-based Service Discovery  基于DNS的服务探索) #include <ESP8266WiFi.h>#i

XE6移动开发环境搭建之IOS篇(3):配置虚拟机,设置Mac安装环境(有图有真相)

XE6移动开发环境搭建之IOS篇(3):配置虚拟机,设置Mac安装环境(有图有真相) 2014-08-16 11:44 网上能找到的关于Delphi XE系列的移动开发环境的相关文章甚少,本文尽量以详细的内容.傻瓜式的表达来告诉你想要的答案. 1.创建新的虚拟机--------------------------------------------------------------- 1.创建新的虚拟机. 2.我们自己去决定虚拟机的参数,选择自定义配置,点击'继续'. 3.选择版本:WorkS

作为一个iOS攻城狮不得不了解的网络知识

1.前言: 最为一个iOS开发工程师,不论实在面试时候还是在与服务器人员讨论网络请求相关知识时候都需要具备基础的常识,比如说:OSI.HTTP.HTTP和HTTPS的区别,以及2016年6月1日起苹果APP审核新增内容的IPV6相关知识.在此小编也几乎是从零学起了 2.什么是OSI 我们所说的OSI全名是:开放式系统互联通信参考模型(Open System Interconnection Reference Model),简称OSI模型:首先要了解的是它是一种概念模型,由国际标准化组织(ISO)

VirtualBox 配置网络和Ubuntu16.04更新操作

上章讲到使用VirtualBox安装Ubuntu16.04,现在系统安装好了,我们得给他配置好网络. VirtualBox配置网络首先得确认自己物理主机的网络连接方式: 1)直接连交换机 2)通过路由器.这里包括拨号上网,连接wifi,使用校园网等. 如果是第一种情况,则使用桥接网络,第二种则使用网络地址转换(NAT). 我的是wifi连接所以用了网络地址转换(NAT) 然后可以登录系统,查看网络是否联通.可以ping www.baidu.com测试.网络调通后我们可以远程了,但是由于没有安装s

SpringMVC4零配置

这里对SpringMVC零配置做一个简单的说明 spring4中提供了大量的注解来支持零配置,简要说明如下: @Configuration : 类似于spring配置文件,负责注册bean,对应的提供了@Bean注解.需要org.springframework.web.context.support.AnnotationConfigWebApplicationContext注册到容器中. @ComponentScan : 注解类查找规则定义 <context:component-scan/>

ifcfg系列命令配置网络属性

Linux网络属性配置: 将linux接到网络中的方式: 1. 本地通信:配置IP/NATMASK 2.跨网络通信:配置路由(网关) 3.基于主机名通信:配置DNS服务器地址(域名解析),linux可以配置3个DNS指向 Linux配置网络的方式: 静态指定 动态指定 1.静态指定 指定命令 配置有关网络的配置文件 (1)指定命令,只对当前系统有效 ifcfg家族 iproute2家族 在CentOS7上新增的nm(network Manager)家族 DNS服务器的配置文件位置:/etc/re

菜鸟学Struts2——零配置(Convention )

又是周末,继续Struts2的学习,之前学习了,Struts的原理,Actions以及Results,今天对对Struts的Convention Plugin进行学习,如下图: Struts Convention支持零配置进行开发,也就是约定约定优于配置的方式. (1)环境准备 使用Convention Plugin进行开发,需要引入struts2-convention-plugin,完整的pom.xml依赖如下: 1 <dependency> 2 <groupId>org.apa