Как использовать getnameinfo вместо gethostbyname?
в коде:
if ((host = (struct hostent*) gethostbyname(address) ) == 0) // address is a string
У меня есть предупреждение, когда кросс-компиляция (общая арка) на 4.5.x gcc:
(.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;
Он хорошо компилируется и не возникает ошибки сегментации при запуске, но я не могу подключить к нему свой сервер: (
Ответы
Ответ 1
gethostbyname()
имеет имя → IP-адрес. Его следует заменить на getaddrinfo()
, который может сделать то же самое.
Это означает, что предупреждение полностью неверно. getnameinfo() является заменой gethostbyaddr(), как для поиска IP → имен. Обратная.
name → IP: gethostbyname()
, getaddrinfo()
IP → имя: gethostbyaddr()
, getnameinfo()
Новые функции могут делать больше: они обрабатывают IPv6 и могут переводить строки, такие как "http" до 80 (порт). В будущем они также могут определить, например, TCP должен использоваться для рассматриваемой услуги или SCTP. Интерфейс готов.
Ответ 2
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
);
Изменить. После некоторых исследований я обнаружил, что
getnameinfo(&sa, sizeof(sa), hostname, size_hostname, NULL, NULL, 0);
должно быть достаточно.
Изменить # 2 Я заметил, что вы пытаетесь использовать возвращаемое значение getnameinfo
как имя хоста. Но это неверно, имя хоста сохраняется в указанном указателе host
. Возвращаемое значение указывает, достаточно ли операции. Также посмотрите справочную страницу.