浅析NSNetService和NSNetServiceBrowser

这两个的概念不是我们讨论的内容。

首先,我们要分清楚NSNetService和NSNetServiceBrowser的作用。前者可以是服务提供者生成的一个服务,然后加到runloop中,并运行服务。这样后者就可以获取到该服务的动态,包括发现该服务,该服务移除等。但是发现是一个很轻量的操作,有点像HTTP中的head请求,并不会去获取body。同理,发现服务获取到的NSNetService也是不完整的,不包括txt data,address和port的,但是包括了其他信息,例如name,type,domain。我的验证似乎和http://stackoverflow.com/questions/6167850/nsnetservice-problems的说法有点出入,但是和下面官网的说法是一致的。

NSNetService

The NSNetService class represents a single service (either a remote service that your app wants to use or a local service that your app is publishing). Instances of this class are involved in all of the Bonjour operations described in this chapter.

NSNetService objects that represent remote services come preinitialized with the service name, type, and domain, but no host name, IP address or port number. The name, type, and domain are used to resolve the instance into the information needed to connect to the service (IP addresses and port number) upon request.

NSNetService objects used for publishing local services to the network must be initialized (by your code) with the service name, type, domain, and port number. Bonjour uses this information to announce the availability of your service over the network.

发现service只是开始,接着就要解析。解析有两种,一种是先发现,再对发现的service解析;还有一种是直接解析。

对于直接解析,就几行代码:

_service = [[NSNetService alloc]initWithDomain:@"local." type:@"_marco._tcp" name:@"marco"];
        [_service setDelegate:self];
        [_service resolveWithTimeout:1.0];
        _services = [[NSMutableArray alloc]init];
新建一个和publisher发出的service一样的service,然后设置代理,调用解析方法。

按需求实现代理方法,最关键的一个方法:

- (void)netServiceDidResolveAddress:(NSNetService *)sender
{
    NSLog(@"%s",__func__);
    [_services addObject:sender];
    NSData *address = [sender.addresses firstObject];
    struct sockaddr_in *socketAddress = (struct sockaddr_in *) [address bytes];
    NSString *hostName = [sender hostName];
    Byte *bytes = (Byte *)[[sender TXTRecordData] bytes];
    int8_t lenth = (int8_t)bytes[0];
    const void*textData = &bytes[1];
    NSLog(@"server info: ip:%s, hostName:%@, text:%s, length:%d",inet_ntoa(socketAddress->sin_addr),hostName,textData,lenth);
}

这边我们获取ip,host name,text和text的长度(这里可能需要参考http://www.zeroconf.org/Rendezvous/txtrecords.html)。这边我们用命令行来注册一个service,结果如下:


对于先发现后解析的情况,要实现browser的代理方法,这边比较关键的是didFindService,代码如下:

- (void)netServiceBrowser:(NSNetServiceBrowser *)netServiceBrowser didFindService:(NSNetService *)netService moreComing:(BOOL)moreServicesComing {
    NSLog(@"%s",__func__);
    [_services addObject:netService];
    self.service = netService;
    [netService setDelegate:self];
    [netService resolveWithTimeout:1.0];
}

这里因为ARC的问题,就用属性接收了下发现的service。然后调用resolve解析。结果和上面的一样。

最后,值得一提的是bonjour的目的是广播ip和port。因此直到目前,服务提供方和需求方并未开始直接点对点通信,知道ip和port之后,接下去是socket和stream的事情了。


提供些参考文献:

http://blog.csdn.net/cssmhyl/article/details/7920431

http://2009315319.blog.51cto.com/701759/1179965



  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值