2012-04-27 7 views
13

en código:¿Cómo se usa getnameinfo en lugar de gethostbyname?

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

Tengo advertencia cuando compilación cruzada (arquitectura ARM genérico) en gcc 4.5.x:

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

getnameinfo es:

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

Y tiene más parámetros ... Y estoy confundido con eso, solo necesito que funcione ya que gethostbyname estaba funcionando. ¿Qué parámetro pasar para mantenerlo simple y estúpido como lo era con gethostbyname?

Finalmente aquí está mi intento:

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; 

compila bien y sin fallo de segmentación en el arranque, pero no puedo conectar mi servidor con ella :(

+1

Como marcó la pregunta con [etiqueta: C++], sugiero usar [boost.asio] (http://www.boost.org/doc/libs/1_49_0/doc/html/boost_asio.html) . – Griwes

+0

Gracias. pero aun así no quiero tocar boost. Pero creo que no hay ninguna razón para no usar el impulso, así que creo que voy a echar un vistazo. – Cynede

+0

https://www.google.com/search?btnG=1&pws=0&q=winsock+getnameinfo+tutorial Número 3. – dutt

Respuesta

12

gethostbyname() hace un nombre → Búsqueda IP. Se debe reemplazar con getaddrinfo(), que puede hacer lo mismo.

Esto significa que la advertencia es completamente incorrecta. getnameinfo() es el reemplazo de gethostbyaddr(), tanto para IP → búsquedas de nombre. El revés.

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

Las funciones más nuevas pueden hacer más: que manejan IPv6 y puede traducir cadenas como 'http' a 80 (puerto). En el futuro, también pueden determinar si, por ejemplo, TCP debe usarse para el servicio en cuestión o SCTP. La interfaz está lista.

11

Beej de lo explica bastante bien gethostbyname(). ¿no funciona bien con IPV6 y por lo tanto se debe utilizar en lugar getnameinfo(). Todo lo que tiene que hacer es rellenar las informaciones requeridas, es decir

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

Editar: Después de algunas investigaciones, he descubierto que

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

debería ser suficiente.

Edición # 2 me he dado cuenta de que están tratando de utilizar el valor de retorno de getnameinfo como nombre de host. Pero eso no es correcto, el nombre de host se guarda dentro del puntero host provisto. El valor de retorno indica si la operación fue suficiente. También eche un vistazo a the man page.

+0

Si está imprimiendo la información de su host, es decir, de '* host' y de' * service', ¿está obteniendo el contenido correcto dentro de las cadenas? –

+0

funcionaba bien con gethostbyname, y sin embargo no puedo detectar el error aquí. – Cynede

+0

pero es un ejemplo de getaddrinfo y estoy tratando de usar getnameinfo. – Cynede