C++ 如何使用 getnameinfo 而不是 gethostbyname?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10346194/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 13:55:12  来源:igfitidea点击:

How to use getnameinfo instead of gethostbyname?

c++socketsgccwarningscross-compiling

提问by cnd

in code :

在代码中:

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

I've got warning when cross compiling (generic arm architecture) on 4.5.x gcc :

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

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

getnameinfois:

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

And it got more parameters... And I'm confused with it, I just need it work as gethostbyname were working. What parameter to pass to keep it simple stupid as it was with gethostbyname?

它有更多的参数......我对它感到困惑,我只需要它像 gethostbyname 一样工作。传递什么参数以使其像使用 gethostbyname 一样简单愚蠢?

Finally here is my try:

最后这是我的尝试:

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;

It compiles well and no segmentation fault on start up but I can't connect my server with it :(

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

采纳答案by Robert Siemer

gethostbyname()does a name→IP lookup. It should be replaced with getaddrinfo(), which can do the same.

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

This means the warning is completely wrong.getnameinfo() is the replacement of gethostbyaddr(), both for IP→name lookups. The reverse.

这意味着警告是完全错误的。getnameinfo() 是 gethostbyaddr() 的替代品,都用于 IP→名称查找。相反。

name→IP: gethostbyname(), getaddrinfo()
IP→name: gethostbyaddr(), getnameinfo()

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

The newer functions can do more: they handle IPv6 andcan translate strings like 'http' to 80 (port). In the future they can also determine if e.g. TCP should be used for the service in question or SCTP. The interface is ready.

较新的函数可以做更多的事情:它们处理 IPv6并且可以将像“http”这样的字符串转换为 80(端口)。将来,他们还可以确定是否应将 TCP 或 SCTP 用于所讨论的服务。接口准备好了。

回答by Sebastian Dressler

Beej's explains it pretty good. gethostbyname()does not works well with IPV6 and thus you should use getnameinfo()instead. All you have to do is to fill in the required informations, i.e.

Beej的解释得很好。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
);

Edit: After some research, I've found that

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

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

should be sufficient.

应该足够了。

Edit #2I've noticed you are trying to use the return value of getnameinfoas hostname. But that is not correct, the hostname is saved within the provided hostpointer. The return value indicates whether the operation was sufficient. Also have a look at the man page.

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