iOS and OS X Network Programming Cookbook |Creating an echo server(Bonjour)(上)

来源:互联网 发布:ubuntu虚拟机分区 编辑:程序博客网 时间:2024/05/21 06:46

Bonjour是一种zero configuration networking。

Publishing a Bonjour service


Bonjour allows for the discovery ofnetwork devices and services on an IP network without acentralized server.  

这句话看起来很牛逼的样子

这里publish service用到的是NSNetService,这里发出请求需要异步,NSNetwork使用delegate来处理service publication的通知,一个代理可以处理多个service

一开始定义了三个properties

@property int status;@property (strong, nonatomic) NSNetService *service;@property (retain, nonatomic) NSString *publishedName;

status表示Bonjour publication service 的状态,service就是要发布的对象,publishName代表发布的服务器的名字,除非手动更改名字(publishWithOptions: )在网络发生冲突的时候会进行rename。

如果想要这个类(BonjourPublishService)能够处理多个service,更改service为NSMutableDictionary,key就是publishName

-(void)startServiceOfType:(NSString *)type andPort:(int)port;-(void)stopService;


接下来就是实现这个类

-(void)startServiceOfType:(NSString *)type andPort:(int)port {  self.status = BONJOURPUBLISHSTOPPED;  self.service = [[NSNetService alloc] initWithDomain:@""  type:type name:@"" port:port];  if (self.service) {    [self.service setDelegate:self];    [self.service publish];  }  else {    [[NSNotificationCenter defaultCenter]  postNotificationName:BONJOURNOTIFICATIONSTOP object:nil];} }

这个方法就是用来publish service,有两个参数

type:这里指的是service的type,是一个字符串类型,既包含application layer type也包含transport protocol,格式是_{protocol}._{transport}例如_SFTP._tcp

port:就是端口


创建NSNetService所用到的方法initWithDomain:type:name:port其中的四个参数

domain:@""表示默认

type:service type,就是之前的那个参数type

name:advertise service用到的name,这里用@""代表用device的name来替代,除非本地网络有冲突不会重命名

port:端口


service不为空就设置代理并且发布。如果想disable the renaming of the service,调用publishWithOptions:NSNetServiceNoAutoRename

接下来是stopService

<span style="font-size:14px;">-(void)stopService {     [self.service stop];     [[NSNotificationCenter defaultCenter]       postNotificationName:BONJOURNOTIFICATIONSTOP       object:nil];   }</span>


没什么特别,接下来是NSNetService 的代理设定

-(void)netServiceWillPublish:(NSNetService *)sender {     self.status = BONJOURPUBLISHSTOPPED;}-(void)netServiceDidPublish:(NSNetService *)sender {     self.status = BONJOURPUBLISHSTARTED;     self.publishedName = sender.name;     [[NSNotificationCenter defaultCenter]       postNotificationName:BONJOURNOTIFICATIONSTART       object:nil];   }-(void)netService:(NSNetService *)senderdidNotPublish:(NSDictionary *)errorDict {  self.status = BONJOURPUBLISHSTOPPED;  [[NSNotificationCenter defaultCenter]    postNotificationName:BONJOURNOTIFICATIONSTOP    object:nil];} -(void)netServiceDidStop:(NSNetService *)sender {         self.status = BONJOURPUBLISHSTOPPED;         [[NSNotificationCenter defaultCenter]           postNotificationName:BONJOURNOTIFICATIONSTOP           object:nil];       }


Discovering a Bonjour service

这个部分就是找到刚到发布的service,用到的是NSNetServiceBrowser类,在处理service discovery上也是异步


<span style="font-size:14px;">       @property int status;       @property (strong, nonatomic) NSNetServiceBrowser *serviceBrowser;       @property (strong, nonatomic) NSMutableArray *services;       -(void)startBrowsingForType:(NSString *)type;       -(void)stopBrowsing;</span>


services是用来装发现的所有service

<span style="font-size:14px;">-(void)startBrowsingForType:(NSString *)type;-(void)stopBrowsing;</span><span style="font-size:12px;"></span>


接下来是实现部分

首先进行了初始化init,没什么特别的

-(void)startBrowsingForType:(NSString *)type {           self.serviceBrowser = [[NSNetServiceBrowser alloc] init];           [self.serviceBrowser setDelegate:self];           [self.serviceBrowser searchForServicesOfType:type       inDomain:@""];           self.status = BONJOURBROWSERSEARCHING;}

domain这是设置为@""是指local domain

-(void)stopBrowsing {     [self.serviceBrowser stop];     [self.services removeAllObjects];}

接下来是代理方面

-(void)netServiceBrowserWillSearch:(NSNetServiceBrowser *)   aNetServiceBrowser {     self.status = BONJOURBROWSERSEARCHING;     [self changeNotification];   }-(void)netServiceBrowserDidStopSearch:(NSNetServiceBrowser *)   aNetServiceBrowser {     self.status = BONJOURBROWSERSTOPPED;     [self changeNotification];   }-(void)netServiceBrowser:(NSNetServiceBrowser *)aNetServiceBrowser   didNotSearch:(NSDictionary *)errorDict {     self.status = BONJOURBROWSERSTOPPED;     [self changeNotification];   }-(void)netServiceBrowser:(NSNetServiceBrowser *)aNetServiceBrowser       didFindService:(NSNetService *)aNetService moreComing:(BOOL)       moreComing {         [self.services addObject:aNetService];         if (!moreComing)         [self changeNotification];} -(void)netServiceBrowser:(NSNetServiceBrowser *)aNetServiceBrowser       didRemoveService:(NSNetService *)aNetService moreComing:(BOOL)       moreComing {         [self.services removeObject:aNetService];         if (!moreComing)         [self changeNotification];}  -(void)changeNotification {     [[NSNotificationCenter defaultCenter]       postNotificationName:BONJOURBROWSERNOTIFICATION       object:nil];   }

并没有什么特别


Resolving a Bonjour service

在学会了用NSNetService发布以及用NSNetServiceBrowser找到service后接下来就是解析NSNetService用来连接了

resolve得到的是IP地址/host name 以及端口,在resolve后可以存储,也可以直接连接,推荐直接连接,因为IP地址可能会变化


<span style="font-size:14px;"> -(void)resolveService:(NSNetService *)service {         [service setDelegate:self];         [service resolveWithTimeout:5.0];} -(void)netServiceDidResolveAddress:(NSNetService *)sender {         NSArray *addresses = sender.addresses;       //  Use hostname and port combination if you are saving the       connection information       //     NSString *hostname = sender.hostName;       //     int port = sender.port;         [[NSNotificationCenter defaultCenter]           postNotificationName:BONJOURRESOLVERNOTIFICATION           object:addresses];} -(void)netService:(NSNetService *)sender       didNotResolve:(NSDictionary *)errorDict {           [[NSNotificationCenter defaultCenter] postNotificationName:BON       JOURRESOLVERNOTIFICATION object:nil];       }</span>



page216image16392
记得设置resolveWithTimeout:


准备工作都做好了下一篇就进入正题了



0 0