2012-04-27 13 views
13

in codice:Come utilizzare getnameinfo invece di gethostbyname?

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

Ho avvertimento durante la compilazione incrociata (architettura ARM generico) sulla 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 
); 

Ed ha più parametri ... E sono confuso con esso, ho solo bisogno che funzioni come funzionava gethostbyname. Quale parametro passare per renderlo semplicemente stupido come lo era con gethostbyname?

Infine ecco la mia prova:

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 bene e non per colpa di segmentazione in fase di start up, ma non riesco a collegare il mio server con esso :(

+1

Come hai contrassegnato la domanda con [tag: C++], ti suggerisco di utilizzare [boost.asio] (http://www.boost.org/doc/libs/1_49_0/doc/html/boost_asio.html) . – Griwes

+0

Grazie. ma ancora non voglio toccare boost. Ma penso che non ci sia motivo per non usare boost, quindi penso che darò un'occhiata. – Cynede

+0

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

risposta

12

gethostbyname() fa un nome → Ricerca IP. Dovrebbe essere sostituito con getaddrinfo(), che può fare lo stesso.

Ciò significa che l'avviso è completamente sbagliato. getnameinfo() è la sostituzione di gethostbyaddr(), sia per IP → ricerche di nomi. Il contrario.

nome → IP: gethostbyname(), getaddrinfo()
IP → Nome: gethostbyaddr(), getnameinfo()

Le funzioni più recenti possono fare di più: essi gestire IPv6 e in grado di tradurre le stringhe come 'http' a 80 (porta). In futuro possono anche determinare se ad es. TCP dovrebbe essere usato per il servizio in questione o SCTP. L'interfaccia è pronta.

11

Beej del spiega abbastanza bene gethostbyname(). non fa funziona bene con IPv6 e quindi si dovrebbe usare getnameinfo() posto. Tutto quello che dovete fare è compilare le informazioni richieste, vale a dire

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: Dopo alcune ricerche, ho trovato che

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

dovrebbe essere sufficiente.

Modifica n. 2 Ho notato che stai tentando di utilizzare il valore di ritorno di getnameinfo come nome host. Ma ciò non è corretto, il nome host viene salvato all'interno del puntatore host fornito. Il valore restituito indica se l'operazione è stata sufficiente. Dai un'occhiata anche allo the man page.

+0

Se stai stampando le informazioni del tuo host, ad esempio '* host' e' * service', stai ottenendo il contenuto corretto all'interno delle stringhe? –

+0

funzionava bene con gethostbyname, eppure non riesco a catturare il bug qui. – Cynede

+0

ma è un esempio di getaddrinfo e sto cercando di usare getnameinfo. – Cynede

Problemi correlati