最近工作中遇到了個新需求、需要將域名 解析成ip地址,搜了搜文章博客,發現很多人都是在用C的
struct hostent *gethostbyname(const char *);
對於OC原生的方法還是比較陌生的,因此研究了一下,封了個方法出來,供大家參考使用,話不多說、上代碼
1 #import "TestTools.h" 2 3 #include <netdb.h> 4 #include <sys/socket.h> 5 #include <arpa/inet.h> 6 #include <resolv.h> 7 8 @implementation TestTools 9 10 + (NSString *)realmToIP:(NSString *)hostName{ 11 12 const char *host = [hostName UTF8String]; 13 // Get host entry info for given host 14 struct hostent *remoteHostEnt = gethostbyname(host); 15 16 // Get address info from host entry 17 struct in_addr *remoteInAddr = (struct in_addr *) remoteHostEnt->h_addr_list[0]; 18 19 // Convert numeric addr to ASCII string 20 char *sRemoteInAddr = inet_ntoa(*remoteInAddr); 21 22 return [NSString stringWithFormat:@"%s",sRemoteInAddr]; 23 24 } 25 26 + (NSString*)parsingIPAddress:(NSString*)strHostName 27 { 28 const char* szname = [strHostName UTF8String]; 29 struct hostent* phot ; 30 @try 31 { 32 phot = gethostbyname(szname); 33 } 34 @catch (NSException * e) 35 { 36 return nil; 37 } 38 39 struct in_addr ip_addr; 40 memcpy(&ip_addr,phot->h_addr_list[0],4); 41 42 char ip[20] = {0}; 43 inet_ntop(AF_INET, &ip_addr, ip, sizeof(ip)); 44 45 NSString* strIPAddress = [NSString stringWithUTF8String:ip]; 46 47 return strIPAddress; 48 } 49 50 51 + (NSString*)getIPAddressByHostName:(NSString*)strHostName{ 52 53 Boolean result,bResolved; 54 CFHostRef hostRef; 55 CFArrayRef addresses = NULL; 56 57 const char * hostAdd =[strHostName UTF8String]; 58 59 CFStringRef hostNameRef = CFStringCreateWithCString(kCFAllocatorDefault, hostAdd, kCFStringEncodingASCII); 60 61 hostRef = CFHostCreateWithName(kCFAllocatorDefault, hostNameRef); 62 63 result = CFHostStartInfoResolution(hostRef, kCFHostAddresses, NULL); 64 if (result == TRUE) { 65 addresses = CFHostGetAddressing(hostRef, &result); 66 } 67 68 bResolved = result == TRUE ? true : false; 69 70 if(bResolved) 71 { 72 struct sockaddr_in* remoteAddr; 73 for(int i = 0; i < CFArrayGetCount(addresses); i++) 74 { 75 CFDataRef saData = (CFDataRef)CFArrayGetValueAtIndex(addresses, i); 76 remoteAddr = (struct sockaddr_in*)CFDataGetBytePtr(saData); 77 78 if(remoteAddr != NULL) 79 { 80 //獲取IP地址 81 char ip[16]; 82 strcpy(ip, inet_ntoa(remoteAddr->sin_addr)); 83 return [NSString stringWithUTF8String:ip]; 84 } 85 } 86 } 87 CFRelease(hostNameRef); 88 CFRelease(hostRef); 89 return nil; 90 } 91 92 @end
方法一,二 中 都是利用C的接口來實現,只不過在拿到 hostent * 之后處理的方式不一樣,第二種方法相對要更快一點喲,另外,有些公司的域名可能是對應的服務器集群,會有很多個ip地址,像百度,網易啦這些, 我們默認都是取的數組中的第一個元素,如果你有需求要拿到其他地址, 遍歷 h_addr_list 就可以啦。
方法三,是利用OC原生的方法來實現的,
CFStringCreateWithCString();
CFHostCreateWithName();
我做了一個小小的測試,三個方法 在同一個環境下,對www.baidu.com進行多次解析 求平均值,解析的地址 肯定都是沒問題的啦, 但是解析所用的時間卻不一樣喲,方法二 用時最短,其次是 方法一,方法三最慢。。。
不過他們相差的時間都是 非常非常小的,不到1毫秒的樣子。