- 用于将域名 / 主机名解析为对应的网络 IP 地址
- 函数原型
c
#include <netdb.h>
#include <sys/socket.h> // 依赖套接字相关头文件
struct hostent {
char *h_name; /* 官方域名 */
char **h_aliases; /* 别名*/
int h_addrtype; /* 地址族(地址类型) */
int h_length; /* 地址长度 */
char **h_addr_list; /* 地址列表 */
}
#define h_addr h_addr_list[0] /* 实现向后兼容性 */
struct hostent *gethostbyname(const char *name);
- 参数
| 参数名 | 类型 | 含义与使用说明 |
|---|---|---|
name |
const char * |
待解析的域名 / 主机名字符串 1. 可传入域名(如www.baidu.com)、本地主机名(如localhost );2. 若传入 NULL / 空字符串,默认解析本机主机名;3. const修饰表示入参内容不可被函数修改。 |
- 返回值
- 成功返回 struct hostent 类型的非空指针,指向存储域名解析结果的主机信息结构体,结构体成员对应解析后的主机各类信息,核心成员如下:
| 成员名 | 含义与特性 |
|---|---|
h_name |
主机的正式名称(官方域名) |
h_aliases |
主机的备用名称数组 ,以NULL 结尾的指针,可存储主机的多个别名域名 |
h_addrtype |
主机的地址类型 ,取值为AF_INET(IPv4)或AF_INET6(IPv6),标识地址协议类型 |
h_length |
主机网络地址的长度,单位为字节(如 IPv4 地址长度为 4 字节) |
h_addr_list |
指向主机网络地址的指针数组 ,地址按网络字节顺序 存储,数组以NULL指针终止 |
h_addr |
为兼容旧版本设计,等价于h_addr_list中的第一个网络地址 |
- 失败返回 NULL空指针,且不会设置errno,需通过 全局变量h_errno获取错误码,再调用hstrerror(h_errno)将错误码转为易读的错误信息(需包含<string.h>),常见h_errno错误码:
* HOST_NOT_FOUND:指定的域名 / 主机名不存在;
* TRY_AGAIN:域名服务器暂时不可用,建议重试;
* NO_RECOVERY:域名解析发生不可恢复的错误;
* NO_DATA:主机名存在,但无对应的 IP 地址(如仅有别名无实际 IP)
- demo
c
#include <stdio.h>
#include <netdb.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
int i;
if(argc < 2){
printf("%s <host name>\n", argv[0]);
exit(0);
}
struct hostent *host = gethostbyname(argv[1]);
for(i = 0; host->h_aliases[i] != NULL; i++){
printf("%s\n", host->h_aliases[i]);
}
printf("Address type:%s\n",
host->h_addrtype == AF_INET ? "AF_INET":"AF_INET6");
for(i = 0; host->h_addr_list[i] != NULL; i++){
printf("IP address %d:%s\n", i, inet_ntoa(*(struct in_addr *)host->h_addr_list[i]));
}
endhostent();
return 0;
}