2012-07-20 6 views
8

Beej's Simple Client codice di esempio itera su tutti gli indirizzi IP restituiti da getaddrinfo(), finché non riesce a connettersi al primo. Guarda il codice qui sotto.E 'necessario tentare di connettersi a tutti gli indirizzi restituiti da getaddrinfo()?

È sempre necessario, o è giusto supporre che dobbiamo solo provare a connetterci al primo indirizzo restituito da getaddrinfo()?

memset(&hints, 0, sizeof hints); 
hints.ai_family = AF_UNSPEC; 
hints.ai_socktype = SOCK_STREAM; 

if ((rv = getaddrinfo(argv[1], PORT, &hints, &servinfo)) != 0) { 
    fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); 
    return 1; 
} 

// ------------------------------------------------------------ 
// loop through all the results and connect to the first we can 
for(p = servinfo; p != NULL; p = p->ai_next) { 
    if ((sockfd = socket(p->ai_family, p->ai_socktype, 
      p->ai_protocol)) == -1) { 
     perror("client: socket"); 
     continue; 
    } 

    if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) { 
     close(sockfd); 
     perror("client: connect"); 
     continue; 
    } 

    break; 
} 

risposta

9

Sì, è necessario eseguire l'iterazione su tutti gli indirizzi, in particolare considerare il caso in cui l'host di destinazione ha indirizzi IPv6 abilitati, ma l'host locale no. getaddrinfo() restituirà gli indirizzi di famiglia AF_INET6, ma la chiamata socket() o connect() avrà esito negativo.

E 'anche una possibilità che il vostro host supporta più protocolli di attuazione SOCK_STREAM (diciamo, SCTP oltre a TCP) e l'host di destinazione non lo fa - dal momento che non è stato impostato il ai_protocol membro della struttura suggerimenti, indirizzi che rappresenta tutti i protocolli supporto socket SOCK_STREAM verrà restituito.

0

Supponendo che tu sia nuovo al socket, a questo punto. Sì, è fondamentale perché dopo aver utilizzato getaddrinfo, è possibile recuperare le informazioni sull'indirizzo per ulteriori convalide.

2

Lasciate guardare tit in questo modo ... L'host del server a cui ci si vuole connettere può avere diversi indirizzi ad esso associati, ma il programma server attuale è in ascolto solo su uno di questi indirizzi. Se il tuo cliente non conosce l'indirizzo esatto che sta ascoltando il programma del server, devi provare tutti gli indirizzi che l'host ha fino a quando non trovi quello corretto e puoi connetterti.

+0

O, in pratica, perché un host può avere più indirizzi? L'uso più ovvio è la ridondanza. Se il primo host non risponde potrebbe avere un migliore successo se si cammina l'elenco ... – asveikau

+0

@asveikau La ragione effettiva per cui un host ha più indirizzi può essere diversa. Può essere a causa della ridondanza, o può essere che serve due reti diverse, o una moltitudine di altri motivi. –

+0

Ridondanza o bilanciamento del carico. – Lothar

1

Sì, dovresti collegarli tutti - non è garantito che il primo (o qualsiasi altro sia scelto) degli indirizzi sia effettivamente valido. Ecco perché è fatto così nel tutorial.

4

In aggiunta alle altre risposte sopra riportate, si consideri il caso comune secondo cui per i siti Web di dimensioni maggiori e così via è possibile pubblicare più record A, a fini di ridondanza. Se un connect() al primo indirizzo non riesce, si desidera provare anche gli altri.

Problemi correlati