gethostbyname函数用法详解
gethostbyname函数简介
- 头文件包含
#include <netdb.h>
- 函数定义
extern int h_errno;
struct hostent *gethostbyname(const char * name );
struct hostent *gethostbyaddr(const void * addr ,
socklen_t len , int type );
void sethostent(int stayopen );
void endhostent(void);
void herror(const char * s );
const char *hstrerror(int err );
struct hostent *gethostent(void);
struct hostent *gethostbyname2(const char * name , int af );
int gethostent_r(
struct hostent * ret , char * buf , size_t buflen ,
struct hostent ** result , int * h_errnop );
int gethostbyaddr_r(const void * addr , socklen_t len , int type ,
struct hostent * ret , char * buf , size_t buflen ,
struct hostent ** result , int * h_errnop );
int gethostbyname_r(const char * name ,
struct hostent * ret , char * buf , size_t buflen ,
struct hostent ** result , int * h_errnop );
int gethostbyname2_r(const char * name , int af,
struct hostent * ret , char * buf , size_t buflen ,
struct hostent ** result , int * h_errnop );
gethostbyname函数常见使用错误
- 编译错误
warning: implicit declaration of function ‘gethostbyname’ [-Wimplicit-function-declaration]
解决办法:包含头文件
#include <netdb.h>
gethostbyname函数详细描述
gethostbyname* () gethostbyaddr* () herror ()和hstrerror ()函数已过时。应用程序应该改用getaddrinfo (3)、getnameinfo (3)和gai_strerror (3)。
gethostbyname ()函数为给定的主机name 返回hostent类型的结构,这里name是主机名或标准点表示法的IPv4地址(对于inet_addr (3)),如果name是IPv4地址,则不执行查找,gethostbyname ()只是将name复制到返回的hostent结构的h_name字段中,将其等价物struct in_addr复制到h_addr_list[0]字段中。如果name不以点结尾,并且设置了环境变量 HOSTALIASES ,则将首先在 HOSTALIASES 指向的别名文件中搜索name(有关文件格式,请参见hostname (7))。除非name以点结尾,否则将搜索当前域及其父域。
对于长度为len和地址类型为type的给定主机地址addr,函数返回hostent类型的结构。有效的地址类型是 AF_INET 和AF_INET6 。主机地址参数是一个指向结构类型的指针,该结构类型取决于地址类型,例如struct in_addr *(可能通过调用inet_addr (3))获取地址类型AF_INET
如果stayopen为true(1),sethostent ()函数指定连接的TCP套接字应该用于名称服务器查询,并且在连续查询期间连接应该保持打开。否则,名称服务器查询将使用UDP数据报。
endhostent ()函数结束对名称服务器查询的TCP连接的使用。
(过时的)herror ()函数打印与stderr上h_errno的当前值相关联的错误消息。
(过时的)hstrerror ()函数接受一个错误号(通常是h_errno)并返回相应的消息字符串。
gethostbyname ()和gethostbyaddr ()执行的域名查询依赖于名称服务交换机( nsswitchconf (5))配置的源或本地名称服务器( named (8))。默认操作是查询名称服务交换机( nsswitchconf (5))配置的源,否则,本地名称服务器( named (8)) Historical nsswitchconf (5)文件是控制主机查找顺序的现代方式。
在glibc2.4和更早版本中,order关键字用于控制/etc/hostconf ( hostconf (5))中定义的主机查找顺序
struct hostent {
char *h_name; /* official name of host */
char **h_aliases; /* alias list */
int h_addrtype; /* host address type */
int h_length; /* length of address */
char **h_addr_list; /* list of addresses */
}
#define h_addr h_addr_list[0] /* for backward compatibility */
hostent结构的成员包括:
- h_name主机的正式名称。
- h_aliases主机的替代名称数组,以空指针终止。
- h_addrtype地址的类型;目前总是 AF_INET 或 AF_INET6 。
- h_length地址的长度,以字节为单位。
- h_addr_list指向主机网络地址的指针数组(按网络字节顺序),以空指针终止。
- h_addr h_addr_list中的第一个地址,用于向后兼容。
gethostbyname函数返回值
如果出现错误,gethostbyname ()和gethostbyaddr ()函数将返回hostent结构或空指针。出错时,h_errno变量保存一个错误号。当非空时,返回值可能指向静态数据,请参见下面的注释。
gethostbyname函数错误码
变量h_errno可以具有以下值:
- HOST_NOT_FOUND 指定的主机未知。
- NO_DATA请求的名称有效,但没有IP地址。对该域的名称服务器的另一种类型的请求可能会返回一个答案。常数NO_ADDRESS是NO_DATA 的同义词
- NO_RECOVERY 出现不可恢复的名称服务器错误。
- TRY_AGAIN 权威名称服务器上出现临时错误。请稍后再试。
gethostbyname函数其他说明
函数gethostbyname ()和gethostbyaddr ()可能会返回指向静态数据的指针,这些指针可能会被以后的调用覆盖。复制struct hostent是不够的,因为它包含指针;需要深度副本。
在最初的BSD实现中,gethostbyname ()的len参数是int .SUSv2标准有缺陷,并声明gethostbyaddr ()的len参数是size_t 类型(这是错误的,因为它必须是int ,而size_t不是。POSIX.1-2001使其成为socklen_t ,这是可以的。)另见accept (2)
gethostbyaddr ()的BSD原型使用"const char\ *"作为第一个参数。System V/POSIX extension POSIX需要gethostent ()调用,它应该返回主机数据库中的下一个条目。当使用DNS/BIND时,这没有多大意义,但是如果主机数据库是一个可以逐行读取的文件,这可能是合理的。在许多系统上,这个名称的例程从文件/etc/hosts 中读取,只有当库是在没有DNS支持的情况下构建的时,它才可用。glibc版本将忽略ipv6条目。这个函数是不可重入的,glibc增加了一个可重入版本gethostent_r () GNU extensions Glibc2也有一个gethostbyname2 (),它的工作方式类似于gethostbyname (),但允许指定地址必须属于的地址族。
Glibc2也有可重入版本gethostent_r () gethostbyaddr_r () gethostbyname_r ()和gethostbyname2_r ()。调用者提供一个hostent结构ret,它将在成功时被填充,以及一个大小为buflen 的临时工作缓冲区buf。调用后,result将在成功时指向结果。如果出现错误或找不到条目,result将为空。函数成功时返回0,失败时返回非零错误号。除了这些函数的不可重入版本返回的错误之外,如果buf太小,函数将返回ERANGE ,并且应该使用更大的缓冲区重试调用。不修改全局变量h_errno,但在h_errnop 中传递用于存储错误号的变量的地址
评论区