GETNAMEINFO - Linux手册页

Linux程序员手册 第3部分
更新日期: 2020-06-09

备注

为了帮助程序员为提供的缓冲区选择合理的大小,请定义常量

#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。

属性

有关本节中使用的术语的说明,请参见attribute(7)。

InterfaceAttributeValue
getnameinfo()Thread safetyMT-Safe env locale

说明

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处理。

名称

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

遵循规范

POSIX.1-2001,POSIX.1-2008,RFC 2535。

返回值

成功后,将返回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)函数将这些错误代码转换为人类可读的字符串,适用于错误报告。

示例

以下代码尝试获取给定套接字地址的数字主机名和服务名。请注意,没有对特定地址系列的硬编码引用。

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()的示例程序。

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/

文件

/ etc / hosts
/etc/nsswitch.conf
/etc/resolv.conf

另外参见

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月

版本

从2.1版开始,glibc中提供了getnameinfo()。

日期:2019-08-20 18:00:29 来源:oir作者:oir