GETNAMEINFO - Linux手册页
Linux程序员手册 第3部分
更新日期: 2020-06-09
名称
getnameinfo-以协议无关的方式进行地址到名称的转换
语法
#include <sys/socket.h> #include <netdb.h> int getnameinfo(const struct sockaddr *addr, socklen_t addrlen, char *host, socklen_t hostlen, char *serv, socklen_t servlen, int flags);
glibc的功能测试宏要求(请参阅feature_test_macros(7)):
getnameinfo():
从glibc 2.22开始:_POSIX_C_SOURCE> = 201112L
Glibc 2.21及更早版本:_POSIX_C_SOURCE
说明
getnameinfo()函数与getaddrinfo(3)的过程相反:它以与协议无关的方式将套接字地址转换为相应的主机和服务。它结合了gethostbyaddr(3)和getservbyport(3)的功能,但是与那些功能不同,getnameinfo()是可重入的,并允许程序消除IPv4对IPv6的依赖性。
addr参数是一个指向大小为addrlen的通用套接字地址结构(类型为sockaddr_in或sockaddr_in6)的指针,该结构保存输入IP地址和端口号。参数host和serv是指向调用者分配的缓冲区(大小分别为hostlen和servlen)的指针,getnameinfo()将包含主机名和服务名的以空终止的字符串分别放入其中。
调用方可以通过提供NULL主机(或serv)参数或零hostlen(或servlen)参数来指定不需要主机名(或服务名)。但是,必须至少请求主机名或服务名之一。
flags参数修改getnameinfo()的行为,如下所示:
- NI_NAMEREQD
- 如果设置,则如果无法确定主机名,则返回错误。
- NI_DGRAM
- 如果设置,则该服务基于数据报(UDP),而不是基于流(TCP)。这对于为UDP和TCP具有不同服务的少数端口(512-514)是必需的。
- NI_NOFQDN
- 如果设置,则仅返回本地主机的标准域名的主机名部分。
- NI_NUMERICHOST
- 如果设置,则返回主机名的数字形式。 (如果未设置,则在无法确定节点名称的情况下仍然会发生这种情况。)
- NI_NUMERICSERV
- 如果设置,则返回服务地址的数字形式。 (如果未设置,则在无法确定服务名称的情况下仍然会发生这种情况。)
Extensions to getnameinfo() for Internationalized Domain Names
从glibc 2.3.4开始,对getnameinfo()进行了扩展,以选择性地允许主机名与国际化域名(IDN)格式进行透明转换(请参阅RFC 3490,应用程序中的国际化域名(IDNA))。定义了三个新标志:
- NI_IDN
- 如果使用此标志,则在必要时将在查找过程中找到的名称从IDN格式转换为语言环境的编码。仅ASCII的名称不受转换的影响,这使得该标志可在现有程序和环境中使用。
- NI_IDN_ALLOW_UNASSIGNED, NI_IDN_USE_STD3_ASCII_RULES
- 设置这些标志将分别使IDNA_ALLOW_UNASSIGNED(允许未分配的Unicode代码点)和IDNA_USE_STD3_ASCII_RULES(检查输出以确保它符合STD3主机名)标志分别用于IDNA处理。
返回值
成功后,将返回0,并且节点和服务名称(如果要求)将填充以null终止的字符串,可能会被截断以适合指定的缓冲区长度。发生错误时,将返回以下非零错误代码之一:
- EAI_AGAIN
- 该名称目前无法解析。稍后再试。
- EAI_BADFLAGS
- flags参数的值无效。
- EAI_FAIL
- 发生了不可恢复的错误。
- EAI_FAMILY
- 无法识别地址族,或地址长度对于指定族无效。
- EAI_MEMORY
- 内存不足。
- EAI_NONAME
- 该名称无法解析提供的参数。 NI_NAMEREQD已设置,无法找到主机名,或者既未请求主机名也未请求服务名。
- EAI_OVERFLOW
- host或serv指向的缓冲区太小。
- EAI_SYSTEM
- 发生系统错误。错误代码可以在errno中找到。
gai_strerror(3)函数将这些错误代码转换为人类可读的字符串,适用于错误报告。
文件
/ etc / hosts
/etc/nsswitch.conf
/etc/resolv.conf
版本
从2.1版开始,glibc中提供了getnameinfo()。
属性
有关本节中使用的术语的说明,请参见attribute(7)。
Interface | Attribute | Value |
getnameinfo() | Thread safety | MT-Safe env locale |
遵循规范
POSIX.1-2001,POSIX.1-2008,RFC 2535。
备注
为了帮助程序员为提供的缓冲区选择合理的大小,请定义常量
#define NI_MAXHOST 1025 #define NI_MAXSERV 32
从glibc 2.8开始,仅在定义了适当的功能测试宏后才公开这些定义,这些宏是:_GNU_SOURCE,_DEFAULT_SOURCE(自glibc 2.19起),或(在glibc版本直至2.19(含2.19)中)
前者是BIND头文件最新版本中的常量MAXDNAME。后者是基于当前"分配的号码" RFC中列出的服务的猜测。
在glibc 2.2版之前,hostlen和servlen参数键入为size_t。
示例
以下代码尝试获取给定套接字地址的数字主机名和服务名。请注意,没有对特定地址系列的硬编码引用。
struct sockaddr *addr; /* input */ socklen_t addrlen; /* input */ char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; if (getnameinfo(addr, addrlen, hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV) == 0) printf("host=%s, serv=%s\n", hbuf, sbuf);
以下版本检查套接字地址是否具有反向地址映射。
struct sockaddr *addr; /* input */ socklen_t addrlen; /* input */ char hbuf[NI_MAXHOST]; if (getnameinfo(addr, addrlen, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD)) printf("could not resolve hostname"); else printf("host=%s\n", hbuf);
在getaddrinfo(3)中可以找到使用getnameinfo()的示例程序。
另外参见
accept(2),getpeername(2),getsockname(2),recvfrom(2),socket(2),getaddrinfo(3),gethostbyaddr(3),getservbyname(3),getservbyport(3),inet_ntop(3),主机(5),服务(5),主机名(7),命名(8)
R.Gilligan,S.Thomson,J.Bound和W.Stevens,《 IPv6的基本套接字接口扩展》(RFC 2553),1999年3月。
Tatsuya Jinmei和Atsushi Onoe,IPv6范围地址的格式扩展,互联网草案,正在进行中
Craig Metz,使用套接字API的协议独立性,freenix记录,2000年:USENIX年度技术会议,2000年6月
出版信息
这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/。