如何使用getnameinfo而不是gethostbyname?

时间:2012-04-27 07:01:50

标签: c++ sockets gcc warnings cross-compiling

代码:

if ((host = (struct hostent*) gethostbyname(address) ) == 0) // address is a string

我在4.5.x gcc上交叉编译(通用arm架构)时收到警告:

(.text+0x1558): warning: gethostbyname is obsolescent, use getnameinfo() instead.

getnameinfo是:

int WSAAPI getnameinfo(
  __in   const struct sockaddr FAR *sa,
  __in   socklen_t salen,
  __out  char FAR *host,
  __in   DWORD hostlen,
  __out  char FAR *serv,
  __in   DWORD servlen,
  __in   int flags
);

它有更多参数......而且我对它感到困惑,我只需要它就像gethostbyname正在工作一样。传递什么参数以保持简单愚蠢与gethostbyname一样?

最后这是我的尝试:

struct sockaddr_in servAddr;
struct hostent *host;        /* Structure containing host information */

/* open socket */
if ((handle = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
    return LILI_ERROR;

memset(&servAddr, 0, sizeof(servAddr));
servAddr.sin_family      = AF_INET;
servAddr.sin_addr.s_addr = inet_addr(address.ptr());
servAddr.sin_port        = htons(port);

char servInfo[NI_MAXSERV];
if ( ( host = (hostent*) getnameinfo(
                 (struct sockaddr *) &servAddr
                 ,sizeof (struct sockaddr)
                 ,address.ptr(), address.size()
                 ,servInfo, NI_MAXSERV
                 ,NI_NUMERICHOST | NI_NUMERICSERV )  ) == 0)
    return LILI_ERROR;

if (::connect(handle, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0)
    return LILI_ERROR;

它编译得很好,启动时没有分段错误,但我无法连接我的服务器:(

2 个答案:

答案 0 :(得分:13)

gethostbyname()进行名称→IP查找。它应该替换为 getaddrinfo() ,它可以做同样的事情。

这意味着警告完全错误。 getnameinfo()取代了gethostbyaddr(),用于IP→名称查找。相反。

名称→IP:gethostbyname()getaddrinfo()
IP→名称:gethostbyaddr()getnameinfo()

较新的功能可以做得更多:它们处理IPv6 并且可以将像'http'这样的字符串翻译为80(端口)。将来他们还可以确定是否TCP应该用于有问题的服务或SCTP。界面准备就绪。

答案 1 :(得分:11)

Beej's解释得非常好。 gethostbyname()与IPV6不兼容,因此您应该使用getnameinfo()。您所要做的就是填写所需的信息,即

getnameinfo(
    &sa,             // Pointer to your struct sockaddr
    sizeof sa,       // Size of this struct
    host,            // Pointer to hostname string
    sizeof host,     // Size of this string
    service,         // Pointer to service name string
    sizeof service,  // Size of this string
    0                // No flags given
);

编辑:经过一番研究,我发现了

getnameinfo(&sa, sizeof(sa), hostname, size_hostname, NULL, NULL, 0);

应该足够了。

编辑#2 我注意到您正在尝试使用getnameinfo的返回值作为主机名。但这不正确,主机名保存在提供的host指针中。返回值表示操作是否足够。另请查看the man page