Beej’s Simple Client example code iterates over all IP addresses returned from getaddrinfo(), until it can connect to the first one. See the code below.
Is this always necessary, or is it OK to assume that we only have to try to connect to the first address returned by 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;
}
Yes, you should iterate over all the addresses – in particular, consider the case when the destination host has IPv6 addresses enabled but your local host does not.
getaddrinfo()will returnAF_INET6family addresses, but then either thesocket()orconnect()call will fail.It’s also a possibility that your host supports multiple protocols implementing
SOCK_STREAM(say, SCTP in addition to TCP) and the destination host does not – since you haven’t set theai_protocolmember of the hints structure, addresses representing all protocols supportingSOCK_STREAMsockets will be returned.