//思路:1.gethostbyname(szname);取得主機信息結構體
// 2.memcpy(&ip_addr,phot->h_addr_list[0],4);從主機信息結構體中取出需要的32位ip地址ip_addr(二進制的)
// 3.inet_ntop(AF_INET, &ip_addr, ip, sizeof(ip));//將二進制整數轉換為點分十進制
#pragma mark 域名解析ip
-(NSString*)getIPAddressByHostName:(NSString*)strHostName
{
//hostent是一個結構體,記錄主機的相關信息,該結構記錄主機的信息,包括主機名、別名、地址類型、地址長度和地址列表。
//struct hostent *gethostbyname(const char *name),gethostbyname函數根據域名解析出服務器的ip地址,它返回一個結構體struct hostent
const char* szname = [strHostName UTF8String];
struct hostent* phot ;
@try
{
phot = gethostbyname(szname);
}
@catch (NSException * e)
{
return nil;
}
// struct in_addr {
// in_addr_t s_addr;
// };
// 結構體in_addr 用來表示一個32位的IPv4地址.
// in_addr_t 一般為 32位的unsigned int,其字節順序為網絡順序(network byte ordered),即該無符號整數采用大端字節序[1] 。.
// 其中每8位代表一個IP地址位中的一個數值.
// 例如192.168.3.144記為0xc0a80390,其中 c0 為192 ,a8 為 168, 03 為 3 , 90 為 144
// 打印的時候可以調用inet_ntoa()函數將其轉換為char *類型.
struct in_addr ip_addr;
if(phot)
{
memcpy(&ip_addr,phot->h_addr_list[0],4);
//void *memcpy(void *dest, const void *src, size_t n);
//從源src所指的內存地址的起始位置開始拷貝n個字節到目標dest所指的內存地址的起始位置中
//h_addr_list[0]里4個字節,每個字節8位,此處為一個數組,一個域名對應多個ip地址或者本地時一個機器有多個網卡
}
else
{
return nil;
}
char ip[20] = {0};
inet_ntop(AF_INET, &ip_addr, ip, sizeof(ip));//將二進制整數轉換為點分十進制
NSString* strIPAddress = [NSString stringWithUTF8String:ip];
return strIPAddress;
}
知識點補充:
/* try
{ //這里是TRY開始,程序開始捕獲異常
//如果有異常 進入 catch {} 然后再進入 finally{}
//如果沒異常 直接進入 finally{}
//Try結束
}
catch (SqlException ex)
{
//catch 有異常才會進入我這里
return false;
}
finally
{
//無論如何都會進入我這里,這里適合做一些釋放資源的事情
//這里可以舍去不用
}*/
// const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt);
// 這個函數轉換網絡二進制結構到ASCII類型的地址,參數的作用和inet_pton相同,只是多了一個參數socklen_t cnt,他是所指向緩存區dst的大小,避免溢出,如果緩存區太小無法存儲地址的值,則返回一個空指針,並將errno置為ENOSPC。
點分十進制(Dotted Decimal Notation)全稱為點分(點式)十進制表示法,是IPv4的IP地址標識方法。IPv4中用四個字節表示一個IP地址,每個字節按照十進制表示為0~255。點分十進制就是用4個從0~255的數字,來表示一個IP地址。如192.168.1.1。