Подтвердить что ты не робот

Как использовать 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;

Он хорошо компилируется и не возникает ошибки сегментации при запуске, но я не могу подключить к нему свой сервер: (

4b9b3361

Ответ 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. Возвращаемое значение указывает, достаточно ли операции. Также посмотрите справочную страницу.