是否有必要尝试连接getaddrinfo()返回的所有地址?

Phi*_*gan 10 c sockets network-programming getaddrinfo

Beej的Simple Client示例代码遍历从getaddrinfo()返回的所有IP地址,直到它可以连接到第一个IP地址.请参阅下面的代码.

这是否总是必要的,或者可以假设我们只需要尝试连接到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;
}
Run Code Online (Sandbox Code Playgroud)

caf*_*caf 9

是的,您应该遍历所有地址 - 特别是,考虑目标主机启用IPv6地址但本地主机没有启用IPv6地址的情况. getaddrinfo()将返回AF_INET6家庭地址,但随后socket()connect()呼叫将失败.

您的主机也可能支持多个协议实现SOCK_STREAM(例如,除了TCP之外的SCTP)而目标主机不支持 - 因为您尚未设置ai_protocol提示结构的成员,SOCK_STREAM将返回表示支持套接字的所有协议的地址.