iOS- 如何使用Apple的零配置網路通訊協定Bonjour?,ios-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/
本文著作權歸作者和部落格園共有,歡迎轉載,但必須保留此段聲明,且在文章頁面明顯位置給出原文串連。