【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 

posted on 2014-12-27 19:04  onlywish  阅读(1310)  评论(0编辑  收藏  举报

导航