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

11 篇文章 0 订阅

Bonjour是一种zero configuration networking。

Publishing a Bonjour service


Bonjour allows for the discovery of network 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 *)sender
didNotPublish:(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:


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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值