iphone DNS解析和网络测试
#import <CFNetwork/CFHost.h>
#import <netinet/in.h>
#import <netdb.h>
#import <SystemConfiguration/SystemConfiguration.h>
#pragma mark -
#pragma mark DNS解析和网络测试
- (NSString * ) getAddressFromArray:(CFArrayRef) addresses
{
struct sockaddr * addr;
char ipAddress[INET6_ADDRSTRLEN];
CFIndex index, count;
int err;
assert(addresses != NULL);
count = CFArrayGetCount(addresses);
for (index = 0 ; index < count; index ++ ) {
addr = ( struct sockaddr * )CFDataGetBytePtr(CFArrayGetValueAtIndex(addresses, index));
assert(addr != NULL);
/* getnameinfo coverts an IPv4 or IPv6 address into a text string. */
err = getnameinfo(addr, addr -> sa_len, ipAddress, INET6_ADDRSTRLEN, NULL, 0 , NI_NUMERICHOST);
if (err == 0 ) {
NSLog( @" 解析到ip地址:%s\n " , ipAddress);
} else {
NSLog( @" 地址格式转换错误:%d\n " , err);
}
}
return [[[NSString alloc] initWithFormat: @" %s " ,ipAddress] autorelease]; // 这里只返回最后一个,一般认为只有一个地址
}
- ( bool )getReachability:(CFDataRef) data withNameOrAddress:(CFStringRef) nameOrAddress
{
SCNetworkConnectionFlags * flags;
CFIndex length;
char * input;
Boolean success;
assert(data != NULL);
assert(nameOrAddress != NULL);
/* CFStringGetMaximumSizeForEncoding determines max bytes a string of specified length will take up if encoded. */
length = CFStringGetMaximumSizeForEncoding(CFStringGetLength(nameOrAddress), kCFStringEncodingASCII);
input = malloc(length + 1 );
assert(input != NULL);
success = CFStringGetCString(nameOrAddress, input, length + 1 , kCFStringEncodingASCII);
assert(success);
flags = (SCNetworkConnectionFlags * )CFDataGetBytePtr(data);
assert (flags != NULL);
/* If you only have a PPP interface enabled, the flags will be 0 because of a bug. <rdar://problem/3627771> */
if ( * flags == 0 ) NSLog( @" %s -> Reachability Unknown\n " , input);
if ( * flags & kSCNetworkFlagsTransientConnection) NSLog( @" %s -> Transient Connection\n " , input);
if ( * flags & kSCNetworkFlagsReachable) {
NSLog( @" %s -> Reachable\n " , input);
success = YES;
} else {
success = NO;
}
if ( * flags & kSCNetworkFlagsConnectionRequired) NSLog( @" %s -> Connection Required\n " , input);
if ( * flags & kSCNetworkFlagsConnectionAutomatic) NSLog( @" %s -> Connection Automatic\n " , input);
if ( * flags & kSCNetworkFlagsInterventionRequired) NSLog( @" %s -> Intervention Required\n " , input);
if ( * flags & kSCNetworkFlagsIsLocalAddress) NSLog( @" %s -> Is Local Address\n " , input);
if ( * flags & kSCNetworkFlagsIsDirect) NSLog( @" %s -> Is Direct\n " , input);
free(input);
return success;
}
- ( void ) serverResoluton{
CFStringRef hostName = (CFStringRef)self.serverInfo.serverAddress;
CFHostRef host;
CFStreamError error;
Boolean success;
CFArrayRef addressArray;
CFDataRef ReachableData;
assert(hostName != NULL);
/* Creates a new host object with the given name. */
host = CFHostCreateWithName(kCFAllocatorDefault, hostName);
assert(host != NULL);
success = CFHostStartInfoResolution(host, kCFHostAddresses, & error);
if ( ! success) {
NSLog( @" CFHostStartInfoResolution 返回错误 (%d, %ld) " , error.domain, error.error); // 如果解析地址失败,使用直接指定IP
NSLog( @" 启用直接指定IP:%@ " ,self.serverInfo.serverIPAddress);
[self.serverInfo.serverAddress release];
self.serverInfo.serverAddress = self.serverInfo.serverIPAddress;
} else {
addressArray = CFHostGetAddressing(host, nil);
[self.serverInfo.serverAddress release];
self.serverInfo.serverAddress = [[NSString alloc] initWithFormat: @" %@ " ,[self getAddressFromArray:addressArray]];
NSLog( @" 替换地址为:%@ " , self.serverInfo.serverAddress);
}
// 使用新地址来确认可连接性
hostName = (CFStringRef)self.serverInfo.serverAddress;
host = CFHostCreateWithName(kCFAllocatorDefault, hostName);
success = CFHostStartInfoResolution(host, kCFHostReachability, & error);
if ( ! success) {
NSLog( @" CFHostStartInfoResolution 返回错误 (%d, %ld) " , error.domain, error.error);
// 暂不知到这里会在什么情况下发生
} else {
ReachableData = CFHostGetReachability(host, nil);
success = [self getReachability:ReachableData withNameOrAddress:(CFStringRef)hostName];
if ( ! success) {
[self.serverInfo.serverAddress release];
self.serverInfo.serverAddress = self.serverInfo.serverAddressBak; // 在这里添加备用服务器
}
}
}
#import <netinet/in.h>
#import <netdb.h>
#import <SystemConfiguration/SystemConfiguration.h>
#pragma mark -
#pragma mark DNS解析和网络测试
- (NSString * ) getAddressFromArray:(CFArrayRef) addresses
{
struct sockaddr * addr;
char ipAddress[INET6_ADDRSTRLEN];
CFIndex index, count;
int err;
assert(addresses != NULL);
count = CFArrayGetCount(addresses);
for (index = 0 ; index < count; index ++ ) {
addr = ( struct sockaddr * )CFDataGetBytePtr(CFArrayGetValueAtIndex(addresses, index));
assert(addr != NULL);
/* getnameinfo coverts an IPv4 or IPv6 address into a text string. */
err = getnameinfo(addr, addr -> sa_len, ipAddress, INET6_ADDRSTRLEN, NULL, 0 , NI_NUMERICHOST);
if (err == 0 ) {
NSLog( @" 解析到ip地址:%s\n " , ipAddress);
} else {
NSLog( @" 地址格式转换错误:%d\n " , err);
}
}
return [[[NSString alloc] initWithFormat: @" %s " ,ipAddress] autorelease]; // 这里只返回最后一个,一般认为只有一个地址
}
- ( bool )getReachability:(CFDataRef) data withNameOrAddress:(CFStringRef) nameOrAddress
{
SCNetworkConnectionFlags * flags;
CFIndex length;
char * input;
Boolean success;
assert(data != NULL);
assert(nameOrAddress != NULL);
/* CFStringGetMaximumSizeForEncoding determines max bytes a string of specified length will take up if encoded. */
length = CFStringGetMaximumSizeForEncoding(CFStringGetLength(nameOrAddress), kCFStringEncodingASCII);
input = malloc(length + 1 );
assert(input != NULL);
success = CFStringGetCString(nameOrAddress, input, length + 1 , kCFStringEncodingASCII);
assert(success);
flags = (SCNetworkConnectionFlags * )CFDataGetBytePtr(data);
assert (flags != NULL);
/* If you only have a PPP interface enabled, the flags will be 0 because of a bug. <rdar://problem/3627771> */
if ( * flags == 0 ) NSLog( @" %s -> Reachability Unknown\n " , input);
if ( * flags & kSCNetworkFlagsTransientConnection) NSLog( @" %s -> Transient Connection\n " , input);
if ( * flags & kSCNetworkFlagsReachable) {
NSLog( @" %s -> Reachable\n " , input);
success = YES;
} else {
success = NO;
}
if ( * flags & kSCNetworkFlagsConnectionRequired) NSLog( @" %s -> Connection Required\n " , input);
if ( * flags & kSCNetworkFlagsConnectionAutomatic) NSLog( @" %s -> Connection Automatic\n " , input);
if ( * flags & kSCNetworkFlagsInterventionRequired) NSLog( @" %s -> Intervention Required\n " , input);
if ( * flags & kSCNetworkFlagsIsLocalAddress) NSLog( @" %s -> Is Local Address\n " , input);
if ( * flags & kSCNetworkFlagsIsDirect) NSLog( @" %s -> Is Direct\n " , input);
free(input);
return success;
}
- ( void ) serverResoluton{
CFStringRef hostName = (CFStringRef)self.serverInfo.serverAddress;
CFHostRef host;
CFStreamError error;
Boolean success;
CFArrayRef addressArray;
CFDataRef ReachableData;
assert(hostName != NULL);
/* Creates a new host object with the given name. */
host = CFHostCreateWithName(kCFAllocatorDefault, hostName);
assert(host != NULL);
success = CFHostStartInfoResolution(host, kCFHostAddresses, & error);
if ( ! success) {
NSLog( @" CFHostStartInfoResolution 返回错误 (%d, %ld) " , error.domain, error.error); // 如果解析地址失败,使用直接指定IP
NSLog( @" 启用直接指定IP:%@ " ,self.serverInfo.serverIPAddress);
[self.serverInfo.serverAddress release];
self.serverInfo.serverAddress = self.serverInfo.serverIPAddress;
} else {
addressArray = CFHostGetAddressing(host, nil);
[self.serverInfo.serverAddress release];
self.serverInfo.serverAddress = [[NSString alloc] initWithFormat: @" %@ " ,[self getAddressFromArray:addressArray]];
NSLog( @" 替换地址为:%@ " , self.serverInfo.serverAddress);
}
// 使用新地址来确认可连接性
hostName = (CFStringRef)self.serverInfo.serverAddress;
host = CFHostCreateWithName(kCFAllocatorDefault, hostName);
success = CFHostStartInfoResolution(host, kCFHostReachability, & error);
if ( ! success) {
NSLog( @" CFHostStartInfoResolution 返回错误 (%d, %ld) " , error.domain, error.error);
// 暂不知到这里会在什么情况下发生
} else {
ReachableData = CFHostGetReachability(host, nil);
success = [self getReachability:ReachableData withNameOrAddress:(CFStringRef)hostName];
if ( ! success) {
[self.serverInfo.serverAddress release];
self.serverInfo.serverAddress = self.serverInfo.serverAddressBak; // 在这里添加备用服务器
}
}
}