正确使用getaddrinfo和getnameinfo

Mar*_*ter 3 c ip tcp

在我的C程序中,我getaddrinfo用来从主机名获取IP地址,并getnameinfo从IP地址获取主机名。这两个功能是互补的。我读到man getaddrinfo我必须使用freeaddrinfo()函数释放为动态分配的链表分配的内存res。因此,我的代码如下所示:

if ((err = getaddrinfo(argv[1], NULL, &hints, &res)) != 0) {
  printf("error %d\n", err);
  return 1;
}

addr.s_addr = ((struct sockaddr_in *)(res->ai_addr))->sin_addr.s_addr;
printf("%s\n", inet_ntoa(addr));

freeaddrinfo(res);
Run Code Online (Sandbox Code Playgroud)

但是因为getnameinfo我看不到任何类似的功能,即freenameinfo

为什么在使用时我需要释放getaddrinfo而不是释放getnameinfo。为什么我需要完全腾出空间?较早时,我gethostbyaddr不需要释放内存。为什么这不同。

getaddrinfoover 的优点是gethostbyaddr什么?后者已弃用,仅应使用前者吗?为什么呢

mer*_*011 5

从手册页开始getaddrinfo,它会向您返回一个动态分配的链表。由于它执行了内存分配,因此也将免费处理内存是有意义的。

freeaddrinfo()函数释放为动态分配的链表res分配的内存。

还要注意,函数签名包括一个struct addrinfo **,这很好地暗示了库函数正在代表您进行分配并向您提供指针。

   int getaddrinfo(const char *node, const char *service,
                       const struct addrinfo *hints,
                       struct addrinfo **res);
Run Code Online (Sandbox Code Playgroud)

对于getnameinfo(),它要求调用者(您)分配const struct sockaddr *,因此释放它是调用者(您)的责任,并且没有相应的库调用来释放它。

   int getnameinfo(const struct sockaddr *sa, socklen_t salen,
                   char *host, size_t hostlen,
                   char *serv, size_t servlen, int flags);
Run Code Online (Sandbox Code Playgroud)

在的手册页中gethostbyaddr,它声明自己已弃用。

gethostbyname *(),gethostbyaddr *(),herror()和hstrerror()函数已过时。应用程序应改用getaddrinfo(3),getnameinfo(3)和gai_strerror(3)。

在这一点上,我通常停止阅读,并停止使用gethostbyaddr,而是getaddrinfo改为使用。

为什么不推荐使用这些功能?可能有很多原因,但是Wikipedia告诉我们旧版功能不支持IPv6,正如下面的@R ..所述,它们也不安全。