发现并公布网络服务 <- 网络概述

OS X和iOS提供四个发现并公布网络服务的API。

  • NSNetService —— 适合大多数应用开发的高级OC API。
  • CFNetService —— 适合Core Fondation代码的高级C API。
  • DNS Service Discovery —— 适合跨平台的代码的低级C API。
  • Game Kit 框架 —— 为游戏提供点对点通信的高级OC API,可在本地(使用蓝牙和Wi-Fi)以及全球网络环境下使用。

除了这些API之外,Multipeer Connectivity 框架也提供对安装有同一款(或有相关性)应用的临近设备的相互发现和通信的支持。这些应用的所在设备,使用了基础Wi-Fi、点对点Wi-Fi、以及蓝牙(对于iOS)或者以太网(对于OS X)。

作为规则,你应该为游戏相关的点对点网络只使用Game Kit。对于运行iOS 7及更高版本的iOS设备之间的点对点网络。你应该使用Multipeer Connectivity框架。

为了兼容旧版本的iOS,你也可以使用CFNetService 或 NSNetService 编写自己的网络代码来进行发布。

注意:在支持蓝牙的设备上,蓝牙通讯通过Game Kit是自动使用的。(当通过设置interfaceIndex为kDNSServiceFlagsIncludeP2P来使用DNS Service Discovery C API的时候,使用蓝牙的Bonjour也可以被启用。详情见Bonjour over Bluetooth on iOS 5 and Later。)

Bonjour服务概述

Bonjour服务由三部分组成:

  • 服务名称——这个名字对于在特定电脑上运行的特定应用实例来说必须是唯一的。
  • 服务类型——它对于应用的所有实例都必须是相同的,并且应该向Internet Assigned Numbers Authority(互联网号码分配机构,IANA)注册。
  • 域——如果域是空的,则主机会在它发布或浏览的域中进行选择。

当应用浏览Bonjour服务的时候,它会请求与特定域的特定类型匹配的服务,并且得到匹配的服务名字列表。然后,它会向用户呈现合适的UI。当用户告诉应用连接特定的服务时,应用应该使用连接到服务的(connect-to-service)API来进行连接。(如果因为某些原因无法这样做,该应用可以把服务的名字和端口传递给使用名字连接的(connect-by-name)API;如果通过名字连接的API不可用,该应用可以请求Bonjour来解析主机名,然后该应用可以通过IP地址和端口号来连接)。

发布网络服务

Bonjour零配置网络让你可以在网络上发布网络服务,例如打印机、或者文档同步服务。这里有三种发布网络服务的方式:

  • 对于OC和Core Foundation代码,推荐的方式是使用CFNetServices API。
  • 对于必须可以运行在iOS 和 OS X以外操作系统上的可移植C代码,推荐使用DNS Service Discovery C API。

你可以依照下面的步骤来发布网络服务:

  1. 创建一个socket来监听与服务器的连接。要了解监听网络socket上的连接的推荐方式,请参阅Networking Programming Topics中的Writing a TCP-Based Server。
  2. 创建一个服务对象,提供你的socket端口、域(通常是空字符串)、以及你选择的服务类型字符串:
  • 对于Foundation,使用initWithDomain:type:name:port:方法初始化NSNetService对象。
  • 对于Core Foundation,使用CFNetServiceCreate函数创建CFNetServiceRef对象。
  • 对于DNS Service Discovery API,,调用DNSServiceRegister来返回DNSServiceRef对象。
  1. 分配一个委托或回调:
  • 对于Foundation,使用委托方法给NSNetService对象分配一个委托。
  • 对于Core Foundation,使用CFNetServiceSetClient函数给CFNetServiceRef对象分配一个委托人回调。
  • 对于DNS Service Discovery API,你应该在调用DNSServiceRegister时传递一个委托人回调(或者,一个指向你选择的上下文对象的指针)。此时,除了当发生时处理回调的内容,其他已经完成。
  1. 如有需要,安排或重新安排服务:
  • 对于Foundation,在默认模式下,该服务会在当前运行循环上被自动安排。如果你需要把该对象安排在另一个运行循环或不同的模式下,你应该取消安排并重新安排。
  • 对于Core Foundation,你必须通过调用CFNetServiceScheduleWithRunLoop在运行循环上安排CFNetServicesRef对象。
  • 对于DNS Service Discovery API,调用DNSServiceSetDispatchQueue,在调度队列上安排服务。(如果你必须支持OS X 10.7之前的操作系统,参见SRVResolver样例代码,它是一个说明在没有Grand Central Dispatch的情况下如何使用DNS Service Discovery的例子。)
  1. 如有必要,发布服务:
  • 对于Foundation,通过调用publish方法发布服务。
  • 对于Core Foundation,通过调用CFNetServiceRegisterWithOptions发布服务。
  • 对于DNS Service Discovery API,不需要进一步操作;当你调用DNSServiceRegister的时候,服务就已经发布。

当你的服务发布后,你可以监听socket上的连接,并在连接时设置输入输出流。

重要:如果你创建了一个自定义协议,你应该使用自定义的服务类型,并使用IANA注册这个服务类型。详细信息,参见RFC 6335。

浏览和连接网络服务

寻找和解析网络服务的过程和发布它的过程一样简单。要在OC中浏览网络服务,创建一个NSNetServiceBrowser类的实例,并给它分配一个委托。然后该服务浏览器调用searchForServicesOfType:inDomain:方法。一旦有服务被发现,netServiceBrowser:didFindService:moreComing:委托方法就会被调用。

想要连接服务器,首先通过调用stop来暂停浏览(除非你有特殊的原因要继续浏览),然后用代表服务的NSNetService对象调用getInputStream:outputStream:方法。服务的地址将会自动解析。

你还可以使用带有CFNetServiceRef对象的CFStreamCreatePairWithSocketToNetService方法,来连接Bonjour服务。

重要:如果你正在使用ARC,你应该阅读NSNetService and Automatic Reference Counting (ARC)。

解析网络服务

你或许需要手动解析网络服务,以便提供服务的地址给没有接收到网络服务名称的API。想要在OC中解析网络服务,首先通过调用stop来听值浏览,然后该服务的NSNetService对象调用resolveWithTimeout:方法。

当服务的地址被解析之后,会调用服务的委托中的netServiceDidResolveAddress:方法。然后你可以使用hostName方法访问服务的主机名,或使用addresses方法访问它的地址信息。为了避免不必要的网络流量,你还应该在得到一组地址返回后,让NSNetService对象调用stop。

重要:这个解析过程返回数字的IP地址和主机名。IP地址可以是IPv4和IPv6地址的任意组合。除非你做不寻常的事,否则你通常应该将主机名传递给任何支持主机名的API,而不是直接使用IP地址,否则,你将不得不编写自己的代码来尝试将每个IP地址进行并联或串联(进一步描述在Avoid Resolving DNS Names Before Connecting to a Host中)。

多点连接(Multipeer Connectivity)概述

Multipeer Connectivity(多点连接)框架提供一个在Bonjour顶部的层,它让你与附近设备(通过基础Wi-Fi、点对点Wi-Fi、蓝牙或以太网)上运行的应用通信,而无需为你的应用编写很多网络代码。

使用多点连接,应用可以发布其可用性。然后,它可以发现正在附近其他设备上运行的该应用(或共享同一个服务类型的其他应用),并可以邀请这些附近的点加入会话。如果它们接收邀请,应用就可以指通过一个方法调用发送信息或文本到一个或多个连接的点。

重要:与Bonjour一样,应用必须提供服务类型,并且你应该使用IANA注册服务类型,参见RFC 6335。

如果你需要基于流的通信,应用可以打开单向流到任何连接的点(它也可以打开一个单向流返回到该应用作为响应)。

最后,多点连接提供在会话上下文之外分享少量数据的能力,如果需要,允许你提供给用户一些信息,用户可以在选择点时使用这些信息访问会话。

了解更多

Multipeer Connectivity——阅读Multipeer Connectivity Framework Reference和MultipeerGroupChat样例代码项目

Game Kit——阅读Game Center Programming Guide, Game Kit Framework Reference,以及 GKRocket and GKTank样例代码项目

NSNetService—阅读 NSNetServices and CFNetServices Programming Guide, NSNetServiceBrowser Class Reference, NSNetServiceBrowserDelegate Protocol Reference, 以及 NSNetServiceDelegate Protocol Reference. 样例代码, 参见RemoteCurrency 样例代码项目.

CFNetService—阅读 NSNetServices and CFNetServices Programming Guide 和 CFNetServices Reference.

DNS Service Discovery—阅读 DNS Service Discovery Programming Guide 和 DNS Service Discovery C Reference.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,001评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,210评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,874评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,001评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,022评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,005评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,929评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,742评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,193评论 1 309
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,427评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,583评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,305评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,911评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,564评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,731评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,581评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,478评论 2 352

推荐阅读更多精彩内容