简介
本文紧接上文iOS_Bonjour编程总结一,进一步描述Bonjour编程中客户端编写部分。
1. 浏览服务
我们可以使用NSNetServiceBrowser类来进行服务扫描,浏览服务不需要知道服务端的IP地址,端口等信息,只需要指定在某一个域名下搜索某种类型的服务。浏览服务的代码如下:
- (void)viewDidLoad {
[super viewDidLoad];
if (browser == nil) {
services = [NSMutableArray new];
browser = [[NSNetServiceBrowser alloc] init];
browser.delegate = self;
// 设置type, 和 domain, domain 一般为空,表示当前局域网环境。
[browser searchForServicesOfType:@"_associateHelp._tcp." inDomain:@""];
}
}
我们可以通过NSNetServiceBrowser的代理方法监听浏览服务过程中每个关键节点的的信息。如下:
#pragma mark - NSNetServiceBrowserDelegate
//即将开始扫描
- (void)netServiceBrowserWillSearch:(NSNetServiceBrowser *)browser {
NSLog(@"netServiceBrowserWillSearch");
}
//停止扫描
- (void)netServiceBrowserDidStopSearch:(NSNetServiceBrowser *)browser{
NSLog(@"netServiceBrowserDidStopSearch");
}
//发现服务,moreComing 用来判断还有没有服务过来。
- (void)netServiceBrowser:(NSNetServiceBrowser *)browser didFindService:(NSNetService *)service moreComing:(BOOL)moreComing {
NSLog(@"%@", service.name);
NSLog(@"%@", service.type);
NSLog(@"%ld", service.port);
NSLog(@"didFindService");
//测试代码,这里只有一个服务,我就直接做解析了。
[self connectToService:service];
}
//服务被移除
- (void)netServiceBrowser:(NSNetServiceBrowser *)browser didRemoveService:(NSNetService *)service moreComing:(BOOL)moreComing {
NSLog(@"%@", service.name);
NSLog(@"%@", service.type);
NSLog(@"didRemoveService");
}
- (void)netServiceBrowser:(NSNetServiceBrowser *)browser didNotSearch:(NSDictionary<NSString *, NSNumber *> *)errorDict {
NSLog(@"didNotSearch");
}
//下面两个方法是关于domain域变化的监听。
- (void)netServiceBrowser:(NSNetServiceBrowser *)browser didFindDomain:(NSString *)domainString moreComing:(BOOL)moreComing {
NSLog(@"didFindDomain");
}
- (void)netServiceBrowser:(NSNetServiceBrowser *)browser didRemoveDomain:(NSString *)domainString moreComing:(BOOL)moreComing {
NSLog(@"didRemoveDomain");
}
2. 解析服务
我在搜索到服务的时候就调用了
[self connectToService:service];
-(void)connectToService:(NSNetService *)service {
service.delegate = self;
//解析服务
[service resolveWithTimeout:5];
}
这个方法主要的作用是:在指定的时间内解析服务,解析成功调用NSNetServiceDelegate的netServiceDidResolveAddress, 解析失败调用didNotResolve。
#pragma NSNetServiceDelegate
-(void)netServiceDidResolveAddress:(NSNetService *)sender
{
NSInputStream *iStream;
NSOutputStream *oStream;
BOOL error = NO;
if (![sender getInputStream:&iStream outputStream:&oStream]) {
error = YES;
}
//inputstream
if (iStream != NULL) {
inputStream = iStream;
inputStream.delegate = self;
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
if (inputStream.streamStatus == NSStreamStatusNotOpen) {
[inputStream open];
}
}else{
error = YES;
}
}
- (void)netService:(NSNetService *)sender didNotResolve:(NSDictionary<NSString *,NSNumber *> *)errorDict
{}
3. 交互
在解析服务成功之后,我们就可以拿到服务端的input/output Stream了,之后就可以随意使用流操作进行读写操作。关于socket的使用,可以参考iOS_NSStream使用指南
参考资料
参考三:Apple : Stream Programming Guide
参考四:iOS网络高级编程
交流群
移动开发交流群:264706196
网友评论