Mac&IOS Bonjour

 ##Bonjour
2 2
 
  3
+###一.Bonjour介绍
  4
+一般在进行Socket编程或者网络访问的时候,首先需要确认对方网络服务已经开启,且需要知道对方的域名或地址以及端口,然后才可以进行进一步操作。在互联网上好点,网络服务方一般常年开启,且一般IP地址是固定的,另由于DNS服务的存在,只要记住对方的域名便可以。但是在局域网,设备不一定连在上面,即使连上了,服务也不一定开了,每当设备连接到局域网的时候,IP地址一般都是动态分配的,所以情况变的复杂。Bonjour的存在便是苹果为了解决局域网设备间连接麻烦的问题。   
  5
+直白的说Bonjour就是是一种协议,使得局域网中的计算机可以方便的发布服务,发现服务和连接服务,达到零配置([Zeroconf][link-zeroconf])的目的。
  6
+[link-zeroconf]:http://zeroconf.org
  7
+
  8
+Zeroconf Working Group指出要实现零配置网络服务的3个要求:
  9
+
  10
+>+ IP地址
  11
+>+ **名字** 到 **IP地址** 的转换(即使没有DNS服务器的情况下)
  12
+>+ 发现网络中的服务
  13
+
  14
+对于第一个要求相关系统和设备可以直接支持的,如动态IP地址分配。   
  15
+第二个要求则可以通过多播(UDP协议向局域网内一组机器发送数据)的方式发送 类似DNS查询的请求,开启着的网络服务收到之后便作出回应,告知自己的名字。   
  16
+第三个要求则通过DNS-SD来实现
  17
+
  18
+Bonjour一般的工作模式便是:在同一个局域网中,一方开启服务,通过Bonjour接口将这个服务发布,服务搜索方在服务列表中便可以看到对应的设备的名字,选择设备便可以进行连接了。整个过程无需事先知道服务发布方的IP地址和端口号。   
  19
+我们常用的软件如iTunes的共享,keynote的remote控制或者支持Bonjour协议的打印机都可以看到Bonjour的影子。
  20
+
  21
+
  22
+###二.Bonjour的实现及使用
  23
+从上面的描述可以看出,Bonjour的用途便是在局域网内发布服务和搜索服务。
  24
+下面从实现层面讲解Bonjour。  
  25
+
  26
+|层次|名称|
  27
+|:----|:----|
  28
+|Foundation|NSNetService/NSNetServiceBroswer|
  29
+|CoreFoundation|CFNetService/CFNetServiceBroswer|
  30
+|Low-Level Socket Based API|dns_sd.h(The DNS Service Discovery API)|
  31
+|Multicast DNS Responder|mDNSResponder (开源项目)|
  32
+
  33
+一般情况下我们使用Foundation这一层接口就可以了,也是最方便的。
  34
+当然服务方在发布服务之前你得先启好网络服务,比如listening socket创建好,且开始侦听某个端口,关于socket编程的知识可以查看[Socket编程][link-socket]  
  35
+
  36
+[link-socket]:Socket编程.md   
  37
+
  38
+**1.发布服务**
  39
+
  40
+  netService = [[[NSNetService alloc] initWithDomain:@""
  41
+                                                type:@"_test._tcp"
  42
+                                                name:@""
  43
+                                                port:port] autorelease];
  44
+  if(netService != nil) {
  45
+      [netService scheduleInRunLoop:[NSRunLoop currentRunLoop]
  46
+                                 forMode:NSRunLoopCommonModes];
  47
+      netService.delegate = self;
  48
+      [netService publish];
  49
+  }
  50
+
  51
+**2.浏览服务**
  52
+  
  53
++ 创建Service Broswer, 需要指定service type和domain,得和发布服务时候的type对应。还得设置delegate,然后实现其delegate方法,以便发现了服务之后进行处理以及对发现的服务进行获取IP地址和端口的结果进行处理。
  54
+
  55
+
  56
+    testServiceBrowser = [[NSNetServiceBrowser alloc] init];
  57
+    testServiceBrowser.delegate = self;
  58
+    [testServiceBrowser searchForServicesOfType:@"_test._tcp" inDomain:@""];
  59
+
  60
+
  61
++ 实现Service Broswer 的delegate方法,处理服务增加或减少的事件
  62
+
  63
+
  64
+    //pragma mark NetServiceBroswer Delegate
  65
+    - (void)netServiceBrowser:(NSNetServiceBrowser*)netServiceBrowser
  66
+               didFindService:(NSNetService*)service
  67
+                   moreComing:(BOOL)moreComing {
  68
+        [netServiceArray addObject:service];
  69
+        if (!moreComing) {
  70
+            [serviceTableView reloadData];
  71
+        }
  72
+    }
  73
+  
  74
+    - (void)netServiceBrowser:(NSNetServiceBrowser*)netServiceBrowser
  75
+             didRemoveService:(NSNetService*)service
  76
+                   moreComing:(BOOL)moreComing {
  77
+        [netServiceArray removeObject:service];
  78
+        if (!moreComing) {
  79
+            [serviceTableView reloadData];
  80
+        }
  81
+    }
  82
+    
  83
+    
  84
++ 连接服务
  85
+
  86
+上面发现的Net Service是不带IP地址和端口信息的。   
  87
+从服务列表中选择一个已经发现的服务,进行Resolve,便可以获取服务的详细信息了。
  88
+
  89
+  - (IBAction)connect:(id)sender{
  90
+      NSUInteger selectedRow = [serviceTableView selectedRow];
  91
+      NSNetService *selectedServiece = [netServiceArray objectAtIndex:selectedRow];
  92
+      selectedServiece.delegate = self;
  93
+      [selectedServiece resolveWithTimeout:5.0];
  94
+  }
  95
+  
  96
+Resolve成功
  97
+
  98
+  //NSNetService Delegate
  99
+  - (void)netServiceDidResolveAddress:(NSNetService *)sender{
  100
+        NSLog(@"service ip:%@ port:%d",sender.address,sender.port);
  101
+    if ([sender getInputStream:&inputStream outputStream:&outputStream]) {
  102
+        [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
  103
+                                         forMode:NSDefaultRunLoopMode];
  104
+        [outputStream open];
  105
+        //发送数据
  106
+        NSData *helloData = [@"Hello" dataUsingEncoding:NSUTF8StringEncoding];
  107
+        [outputStream write:[helloData bytes] maxLength:[helloData length]];
  108
+    }
  109
+  }
  110
+  
  111
+上面的代码充分利用了输入输出流进行通信。如果你自己的使用socket的连接也是可以的,因为这个时候已经可以获取了对方的IP地址和端口了。
     

转载自: https://github.com/kejinlu/objc-doc/commit/154ea6af4f281c80453d9e00c348a43075d6d2fe#L1R14
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值