//思路: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。