【iOS】异步解析dns
发现iOS封装的有点恶心,把select封装成了CFRunLoop的形式,又把CFRunLoop封装成了NSRunLoop,跟select使用方式又一样了。 又弄一些玄之又玄的概念,AF_UNIX封装成了NSPort。
项目中遇到了需要异步解析dns的问题,需要解析dns的时候,另一个线程去取消它,但又不能单单的起一个线程,然后强制结束。 这样的退出是不优雅的。
最后自己用C写了一个dns协议… 想整合到socket跨平台框架中, 后来又发现我没有办法获取dhcp获得的dns服务器地址。
最后只能在上层实现了, 使用了CFNetWork.framework,通过标签来取消
#import @interface TSHost : NSObject +(NSArray *)getIpAddress:(NSString *)host label:(NSString *)label; +(void)cancelParse:(NSString *)label; @end // // TSHost.m // dns_simple // // Created by netriver on 14-5-30. // Copyright (c) 2014年 onlywish.me. All rights reserved. // #import "TSHost.h" #include #include #include #include #include static NSMutableDictionary *dic; void host_call_back(CFHostRef theHost, CFHostInfoType typeInfo, const CFStreamError *error, void *info) { } @implementation TSHost +(NSArray *)getIpAddress:(NSString *)host label:(NSString *)label; { if (dic == nil) { dic = [NSMutableDictionary dictionary]; } if ([dic objectForKey:label] != nil) { return nil; } //添加取消接口 NSPort *port = [NSPort port]; [dic setObject:port forKey:label]; [[NSRunLoop currentRunLoop] addPort:port forMode:NSDefaultRunLoopMode]; //解析域名代码 CFHostRef hostref = CFHostCreateWithName(NULL,(__bridge CFStringRef)(host)); //设置异步 CFHostClientContext context; memset(&context,0,sizeof(CFHostClientContext)); CFHostSetClient(hostref, host_call_back, &context); //添加至runloop CFHostScheduleWithRunLoop(hostref,[[NSRunLoop currentRunLoop] getCFRunLoop],kCFRunLoopDefaultMode); NSLog(@"正在解析...."); //开始解析 CFHostStartInfoResolution(hostref,kCFHostAddresses,NULL); //等待完成 [[NSRunLoop currentRunLoop] acceptInputForMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; //取消运行循环 CFHostUnscheduleFromRunLoop(hostref, [[NSRunLoop currentRunLoop] getCFRunLoop], kCFRunLoopDefaultMode); //移除取消接口 [dic removeObjectForKey:label]; [port invalidate]; NSLog(@"解析完成...."); Boolean flag; //取得解析的ip地址 NSArray * array = (__bridge NSArray *)CFHostGetAddressing(hostref, &flag); //释放解析对象 CFRelease(hostref); if (flag == NO) return nil; struct sockaddr_in *sock_ptr; NSMutableArray * result = [NSMutableArray array]; for(NSData * ipaddr in array) { sock_ptr = (struct sockaddr_in *)[ipaddr bytes]; NSString * ip = [NSString stringWithUTF8String:inet_ntoa(sock_ptr->sin_addr)]; [result addObject:ip]; NSLog(@"ip ========= %@",ip); } //CFRelease((__bridge CFTypeRef)(array)); return result; } +(void)cancelParse:(NSString *)label { if (dic == nil) return; NSPort *thePort = [dic objectForKey:label]; if (thePort != nil) { //取消运行循环 [thePort sendBeforeDate:[NSDate date] components:nil from:nil reserved:0]; } } @end
源博客地址 http://onlywish.me
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。