發(fā)現(xiàn)并公布網(wǎng)絡(luò)服務(wù) <- 網(wǎng)絡(luò)概述

OS X和iOS提供四個(gè)發(fā)現(xiàn)并公布網(wǎng)絡(luò)服務(wù)的API。

  • NSNetService —— 適合大多數(shù)應(yīng)用開發(fā)的高級(jí)OC API睁枕。
  • CFNetService —— 適合Core Fondation代碼的高級(jí)C API斋荞。
  • DNS Service Discovery —— 適合跨平臺(tái)的代碼的低級(jí)C API。
  • Game Kit 框架 —— 為游戲提供點(diǎn)對(duì)點(diǎn)通信的高級(jí)OC API柱恤,可在本地(使用藍(lán)牙和Wi-Fi)以及全球網(wǎng)絡(luò)環(huán)境下使用宅广。

除了這些API之外,Multipeer Connectivity 框架也提供對(duì)安裝有同一款(或有相關(guān)性)應(yīng)用的臨近設(shè)備的相互發(fā)現(xiàn)和通信的支持。這些應(yīng)用的所在設(shè)備,使用了基礎(chǔ)Wi-Fi、點(diǎn)對(duì)點(diǎn)Wi-Fi捐晶、以及藍(lán)牙(對(duì)于iOS)或者以太網(wǎng)(對(duì)于OS X)。

作為規(guī)則妄辩,你應(yīng)該為游戲相關(guān)的點(diǎn)對(duì)點(diǎn)網(wǎng)絡(luò)只使用Game Kit惑灵。對(duì)于運(yùn)行iOS 7及更高版本的iOS設(shè)備之間的點(diǎn)對(duì)點(diǎn)網(wǎng)絡(luò)。你應(yīng)該使用Multipeer Connectivity框架眼耀。

為了兼容舊版本的iOS英支,你也可以使用CFNetService 或 NSNetService 編寫自己的網(wǎng)絡(luò)代碼來(lái)進(jìn)行發(fā)布。

注意:在支持藍(lán)牙的設(shè)備上哮伟,藍(lán)牙通訊通過(guò)Game Kit是自動(dòng)使用的干花。(當(dāng)通過(guò)設(shè)置interfaceIndex為kDNSServiceFlagsIncludeP2P來(lái)使用DNS Service Discovery C API的時(shí)候,使用藍(lán)牙的Bonjour也可以被啟用楞黄。詳情見Bonjour over Bluetooth on iOS 5 and Later池凄。)

Bonjour服務(wù)概述

Bonjour服務(wù)由三部分組成:

  • 服務(wù)名稱——這個(gè)名字對(duì)于在特定電腦上運(yùn)行的特定應(yīng)用實(shí)例來(lái)說(shuō)必須是唯一的。
  • 服務(wù)類型——它對(duì)于應(yīng)用的所有實(shí)例都必須是相同的鬼廓,并且應(yīng)該向Internet Assigned Numbers Authority(互聯(lián)網(wǎng)號(hào)碼分配機(jī)構(gòu)肿仑,IANA)注冊(cè)。
  • 域——如果域是空的桑阶,則主機(jī)會(huì)在它發(fā)布或?yàn)g覽的域中進(jìn)行選擇柏副。

當(dāng)應(yīng)用瀏覽Bonjour服務(wù)的時(shí)候勾邦,它會(huì)請(qǐng)求與特定域的特定類型匹配的服務(wù)蚣录,并且得到匹配的服務(wù)名字列表。然后眷篇,它會(huì)向用戶呈現(xiàn)合適的UI萎河。當(dāng)用戶告訴應(yīng)用連接特定的服務(wù)時(shí),應(yīng)用應(yīng)該使用連接到服務(wù)的(connect-to-service)API來(lái)進(jìn)行連接蕉饼。(如果因?yàn)槟承┰驘o(wú)法這樣做虐杯,該應(yīng)用可以把服務(wù)的名字和端口傳遞給使用名字連接的(connect-by-name)API;如果通過(guò)名字連接的API不可用昧港,該應(yīng)用可以請(qǐng)求Bonjour來(lái)解析主機(jī)名擎椰,然后該應(yīng)用可以通過(guò)IP地址和端口號(hào)來(lái)連接)。

發(fā)布網(wǎng)絡(luò)服務(wù)

Bonjour零配置網(wǎng)絡(luò)讓你可以在網(wǎng)絡(luò)上發(fā)布網(wǎng)絡(luò)服務(wù)创肥,例如打印機(jī)达舒、或者文檔同步服務(wù)值朋。這里有三種發(fā)布網(wǎng)絡(luò)服務(wù)的方式:

  • 對(duì)于OC和Core Foundation代碼,推薦的方式是使用CFNetServices API巩搏。
  • 對(duì)于必須可以運(yùn)行在iOS 和 OS X以外操作系統(tǒng)上的可移植C代碼昨登,推薦使用DNS Service Discovery C API。

你可以依照下面的步驟來(lái)發(fā)布網(wǎng)絡(luò)服務(wù):

  1. 創(chuàng)建一個(gè)socket來(lái)監(jiān)聽與服務(wù)器的連接贯底。要了解監(jiān)聽網(wǎng)絡(luò)socket上的連接的推薦方式丰辣,請(qǐng)參閱Networking Programming Topics中的Writing a TCP-Based Server。
  2. 創(chuàng)建一個(gè)服務(wù)對(duì)象禽捆,提供你的socket端口笙什、域(通常是空字符串)、以及你選擇的服務(wù)類型字符串:
  • 對(duì)于Foundation胚想,使用initWithDomain:type:name:port:方法初始化NSNetService對(duì)象得湘。
  • 對(duì)于Core Foundation,使用CFNetServiceCreate函數(shù)創(chuàng)建CFNetServiceRef對(duì)象顿仇。
  • 對(duì)于DNS Service Discovery API,淘正,調(diào)用DNSServiceRegister來(lái)返回DNSServiceRef對(duì)象。
  1. 分配一個(gè)委托或回調(diào):
  • 對(duì)于Foundation臼闻,使用委托方法給NSNetService對(duì)象分配一個(gè)委托鸿吆。
  • 對(duì)于Core Foundation,使用CFNetServiceSetClient函數(shù)給CFNetServiceRef對(duì)象分配一個(gè)委托人回調(diào)述呐。
  • 對(duì)于DNS Service Discovery API惩淳,你應(yīng)該在調(diào)用DNSServiceRegister時(shí)傳遞一個(gè)委托人回調(diào)(或者,一個(gè)指向你選擇的上下文對(duì)象的指針)乓搬。此時(shí)思犁,除了當(dāng)發(fā)生時(shí)處理回調(diào)的內(nèi)容,其他已經(jīng)完成进肯。
  1. 如有需要激蹲,安排或重新安排服務(wù):
  • 對(duì)于Foundation,在默認(rèn)模式下江掩,該服務(wù)會(huì)在當(dāng)前運(yùn)行循環(huán)上被自動(dòng)安排学辱。如果你需要把該對(duì)象安排在另一個(gè)運(yùn)行循環(huán)或不同的模式下,你應(yīng)該取消安排并重新安排环形。
  • 對(duì)于Core Foundation策泣,你必須通過(guò)調(diào)用CFNetServiceScheduleWithRunLoop在運(yùn)行循環(huán)上安排CFNetServicesRef對(duì)象。
  • 對(duì)于DNS Service Discovery API抬吟,調(diào)用DNSServiceSetDispatchQueue萨咕,在調(diào)度隊(duì)列上安排服務(wù)。(如果你必須支持OS X 10.7之前的操作系統(tǒng)火本,參見SRVResolver樣例代碼危队,它是一個(gè)說(shuō)明在沒(méi)有Grand Central Dispatch的情況下如何使用DNS Service Discovery的例子蓄喇。)
  1. 如有必要,發(fā)布服務(wù):
  • 對(duì)于Foundation交掏,通過(guò)調(diào)用publish方法發(fā)布服務(wù)妆偏。
  • 對(duì)于Core Foundation,通過(guò)調(diào)用CFNetServiceRegisterWithOptions發(fā)布服務(wù)盅弛。
  • 對(duì)于DNS Service Discovery API钱骂,不需要進(jìn)一步操作;當(dāng)你調(diào)用DNSServiceRegister的時(shí)候挪鹏,服務(wù)就已經(jīng)發(fā)布见秽。

當(dāng)你的服務(wù)發(fā)布后,你可以監(jiān)聽socket上的連接讨盒,并在連接時(shí)設(shè)置輸入輸出流解取。

重要:如果你創(chuàng)建了一個(gè)自定義協(xié)議,你應(yīng)該使用自定義的服務(wù)類型返顺,并使用IANA注冊(cè)這個(gè)服務(wù)類型禀苦。詳細(xì)信息,參見RFC 6335遂鹊。

瀏覽和連接網(wǎng)絡(luò)服務(wù)

尋找和解析網(wǎng)絡(luò)服務(wù)的過(guò)程和發(fā)布它的過(guò)程一樣簡(jiǎn)單振乏。要在OC中瀏覽網(wǎng)絡(luò)服務(wù),創(chuàng)建一個(gè)NSNetServiceBrowser類的實(shí)例秉扑,并給它分配一個(gè)委托慧邮。然后該服務(wù)瀏覽器調(diào)用searchForServicesOfType:inDomain:方法。一旦有服務(wù)被發(fā)現(xiàn)舟陆,netServiceBrowser:didFindService:moreComing:委托方法就會(huì)被調(diào)用误澳。

想要連接服務(wù)器,首先通過(guò)調(diào)用stop來(lái)暫停瀏覽(除非你有特殊的原因要繼續(xù)瀏覽)秦躯,然后用代表服務(wù)的NSNetService對(duì)象調(diào)用getInputStream:outputStream:方法忆谓。服務(wù)的地址將會(huì)自動(dòng)解析。

你還可以使用帶有CFNetServiceRef對(duì)象的CFStreamCreatePairWithSocketToNetService方法宦赠,來(lái)連接Bonjour服務(wù)陪毡。

重要:如果你正在使用ARC米母,你應(yīng)該閱讀NSNetService and Automatic Reference Counting (ARC)勾扭。

解析網(wǎng)絡(luò)服務(wù)

你或許需要手動(dòng)解析網(wǎng)絡(luò)服務(wù),以便提供服務(wù)的地址給沒(méi)有接收到網(wǎng)絡(luò)服務(wù)名稱的API铁瞒。想要在OC中解析網(wǎng)絡(luò)服務(wù)妙色,首先通過(guò)調(diào)用stop來(lái)聽值瀏覽,然后該服務(wù)的NSNetService對(duì)象調(diào)用resolveWithTimeout:方法慧耍。

當(dāng)服務(wù)的地址被解析之后身辨,會(huì)調(diào)用服務(wù)的委托中的netServiceDidResolveAddress:方法丐谋。然后你可以使用hostName方法訪問(wèn)服務(wù)的主機(jī)名,或使用addresses方法訪問(wèn)它的地址信息煌珊。為了避免不必要的網(wǎng)絡(luò)流量号俐,你還應(yīng)該在得到一組地址返回后,讓NSNetService對(duì)象調(diào)用stop定庵。

重要:這個(gè)解析過(guò)程返回?cái)?shù)字的IP地址和主機(jī)名吏饿。IP地址可以是IPv4和IPv6地址的任意組合。除非你做不尋常的事蔬浙,否則你通常應(yīng)該將主機(jī)名傳遞給任何支持主機(jī)名的API猪落,而不是直接使用IP地址,否則畴博,你將不得不編寫自己的代碼來(lái)嘗試將每個(gè)IP地址進(jìn)行并聯(lián)或串聯(lián)(進(jìn)一步描述在Avoid Resolving DNS Names Before Connecting to a Host中)笨忌。

多點(diǎn)連接(Multipeer Connectivity)概述

Multipeer Connectivity(多點(diǎn)連接)框架提供一個(gè)在Bonjour頂部的層,它讓你與附近設(shè)備(通過(guò)基礎(chǔ)Wi-Fi俱病、點(diǎn)對(duì)點(diǎn)Wi-Fi官疲、藍(lán)牙或以太網(wǎng))上運(yùn)行的應(yīng)用通信,而無(wú)需為你的應(yīng)用編寫很多網(wǎng)絡(luò)代碼亮隙。

使用多點(diǎn)連接袁余,應(yīng)用可以發(fā)布其可用性。然后咱揍,它可以發(fā)現(xiàn)正在附近其他設(shè)備上運(yùn)行的該應(yīng)用(或共享同一個(gè)服務(wù)類型的其他應(yīng)用)颖榜,并可以邀請(qǐng)這些附近的點(diǎn)加入會(huì)話。如果它們接收邀請(qǐng)煤裙,應(yīng)用就可以指通過(guò)一個(gè)方法調(diào)用發(fā)送信息或文本到一個(gè)或多個(gè)連接的點(diǎn)掩完。

重要:與Bonjour一樣,應(yīng)用必須提供服務(wù)類型硼砰,并且你應(yīng)該使用IANA注冊(cè)服務(wù)類型且蓬,參見RFC 6335。

如果你需要基于流的通信题翰,應(yīng)用可以打開單向流到任何連接的點(diǎn)(它也可以打開一個(gè)單向流返回到該應(yīng)用作為響應(yīng))恶阴。

最后,多點(diǎn)連接提供在會(huì)話上下文之外分享少量數(shù)據(jù)的能力豹障,如果需要冯事,允許你提供給用戶一些信息,用戶可以在選擇點(diǎn)時(shí)使用這些信息訪問(wèn)會(huì)話血公。

了解更多

Multipeer Connectivity——閱讀Multipeer Connectivity Framework Reference和MultipeerGroupChat樣例代碼項(xiàng)目

Game Kit——閱讀Game Center Programming Guide, Game Kit Framework Reference昵仅,以及 GKRocket and GKTank樣例代碼項(xiàng)目

NSNetService—閱讀 NSNetServices and CFNetServices Programming Guide, NSNetServiceBrowser Class Reference, NSNetServiceBrowserDelegate Protocol Reference, 以及 NSNetServiceDelegate Protocol Reference. 樣例代碼, 參見RemoteCurrency 樣例代碼項(xiàng)目.

CFNetService—閱讀 NSNetServices and CFNetServices Programming Guide 和 CFNetServices Reference.

DNS Service Discovery—閱讀 DNS Service Discovery Programming Guide 和 DNS Service Discovery C Reference.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子摔笤,更是在濱河造成了極大的恐慌够滑,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,284評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吕世,死亡現(xiàn)場(chǎng)離奇詭異彰触,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)命辖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門渴析,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人吮龄,你說(shuō)我怎么就攤上這事俭茧。” “怎么了漓帚?”我有些...
    開封第一講書人閱讀 164,614評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵母债,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我尝抖,道長(zhǎng)毡们,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,671評(píng)論 1 293
  • 正文 為了忘掉前任昧辽,我火速辦了婚禮衙熔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘搅荞。我一直安慰自己红氯,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評(píng)論 6 392
  • 文/花漫 我一把揭開白布咕痛。 她就那樣靜靜地躺著痢甘,像睡著了一般。 火紅的嫁衣襯著肌膚如雪茉贡。 梳的紋絲不亂的頭發(fā)上塞栅,一...
    開封第一講書人閱讀 51,562評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音腔丧,去河邊找鬼放椰。 笑死,一個(gè)胖子當(dāng)著我的面吹牛愉粤,可吹牛的內(nèi)容都是我干的砾医。 我是一名探鬼主播,決...
    沈念sama閱讀 40,309評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼科汗,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼藻烤!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起头滔,我...
    開封第一講書人閱讀 39,223評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤怖亭,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后坤检,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體兴猩,經(jīng)...
    沈念sama閱讀 45,668評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評(píng)論 3 336
  • 正文 我和宋清朗相戀三年早歇,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了倾芝。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,981評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡箭跳,死狀恐怖晨另,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情谱姓,我是刑警寧澤借尿,帶...
    沈念sama閱讀 35,705評(píng)論 5 347
  • 正文 年R本政府宣布,位于F島的核電站屉来,受9級(jí)特大地震影響路翻,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜茄靠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評(píng)論 3 330
  • 文/蒙蒙 一茂契、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧慨绳,春花似錦掉冶、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至喂江,卻和暖如春召锈,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背获询。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工涨岁, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人吉嚣。 一個(gè)月前我還...
    沈念sama閱讀 48,146評(píng)論 3 370
  • 正文 我出身青樓梢薪,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親尝哆。 傳聞我的和親對(duì)象是個(gè)殘疾皇子秉撇,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容