正确使用getaddrinfo和getnameinfo

时间:2014-05-17 21:29:31

标签: c tcp ip

在我的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);

但对于getnameinfo,我没有看到任何类似的功能,即freenameinfo

为什么我需要在使用getaddrinfo时免费,而不是getnameinfo。为什么我需要自由解脱?早些时候,当我使用gethostbyaddr时,不需要释放内存。为什么会有所不同。

getaddrinfo优于gethostbyaddr的优势是什么?后者是否被弃用,是否只应使用前者?为什么?

1 个答案:

答案 0 :(得分:5)

getaddrinfo的手册页中,它会返回动态分配的链接列表。 由于它执行了内存分配,因此它也可以自由处理内存。

  

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

另请注意,函数签名包含struct addrinfo **,这是一个很好的提示,即库函数代表您进行分配并返回指针。

   int getaddrinfo(const char *node, const char *service,
                       const struct addrinfo *hints,
                       struct addrinfo **res);

对于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);

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

  

gethostbyname *(),gethostbyaddr *(),herror()和hstrerror()   功能已经过时。应用程序应该使用getaddrinfo(3),   取而代之的是getnameinfo(3)和gai_strerror(3)。

此时,我通常会停止阅读,并停止使用gethostbyaddr,而不是getaddrinfo

为什么不推荐使用这些函数?可能有很多原因,但Wikipedia告诉我们遗留函数不支持IPv6和@R。在下面提到,它们not线程安全。