2012-07-20 10 views
8

Beej's Simple Client código de ejemplo itera sobre todas las direcciones IP devueltas desde getaddrinfo(), hasta que se pueda conectar con la primera. Vea el código a continuación.¿Es necesario intentar conectarse a todas las direcciones devueltas por getaddrinfo()?

¿Esto siempre es necesario, o está bien suponer que solo tenemos que intentar conectarnos a la primera dirección devuelta por 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; 
} 

Respuesta

9

Sí, debe iterar sobre todas las direcciones; en particular, considere el caso cuando el host de destino tiene habilitadas las direcciones IPv6 pero su host local no. getaddrinfo() devolverá las direcciones familiares AF_INET6, pero luego la llamada socket() o connect() fallará.

Es también una posibilidad de que su anfitrión es compatible con varios protocolos de aplicación SOCK_STREAM (por ejemplo, SCTP, además de TCP) y el host de destino no lo hace - ya que no se ha establecido el ai_protocol miembro de la estructura de consejos, direcciones representación de todos los protocolos Se devolverán los sockets SOCK_STREAM.

0

Suponiendo que es nuevo en el socket, en este punto. Sí, es crucial porque después de usar getaddrinfo, puede recuperar una información de dirección para una mayor validación.

2

Fíjate en tit de esta manera ... El host del servidor al que deseas conectarte puede tener varias direcciones asociadas, pero el programa del servidor real solo escucha en una de esas direcciones. Si su cliente no sabe la dirección exacta que está escuchando el programa del servidor, debe probar todas las direcciones que tiene el host hasta que encuentre la correcta y pueda conectarse.

+0

O más en la práctica, ¿por qué un host puede tener varias direcciones? El uso más obvio es la redundancia. Si el primer host no responde, puede tener un mayor éxito si recorre la lista ... – asveikau

+0

@asveikau La razón real por la que un host tiene varias direcciones puede diferir. Puede ser debido a la redundancia, o puede ser que sirva para dos redes diferentes, o una multitud de otras razones. –

+0

Redundancia o equilibrio de carga. – Lothar

1

Sí, debe recorrer todas ellas; no hay garantía de que la primera (o lo que elija) de las direcciones sea realmente válida. Es por eso que se hace así en el tutorial.

4

Además de las otras respuestas dadas anteriormente, considere el caso común de que, para sitios web más grandes y demás, se publiquen múltiples registros A, con fines de redundancia. Si falla un connect() a la primera dirección, también debe probar los otros.

Cuestiones relacionadas