-->

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

2019-07-30 12:17发布

Beej的简单的客户端以上)从的getaddrinfo(返回的所有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;
}

Answer 1:

是的,你应该遍历所有的地址 - 特别是考虑当目标主机启用了IPv6地址,但本地主机没有。 getaddrinfo()将返回AF_INET6家庭地址,但无论是socket()connect()调用将失败。

这也是您的主机支持多种协议实现的可能性SOCK_STREAM (比如说,SCTP除了TCP)和目标主机不-因为你还没有设置ai_protocol的线索结构的成员,代表支持所有协议地址SOCK_STREAM插座会返回。



Answer 2:

除了上面给出的其他答案,考虑到通常情况下,对于大型网站等,多个A记录可能会被公开,用于冗余的目的。 如果connect()首地址失败,你想尝试一下其他人。



Answer 3:

让我们来看看针锋相对这样......你要连接到可能有与之相关联的几个IP地址的服务器主机,但实际的服务器程序只侦听这些地址之一。 如果您的客户端不知道服务器程序是听的确切地址,你必须尝试所有的主机具有地址,直到找到正确的和可以连接。



Answer 4:

是的,你应该遍历所有的人 - 有没有地址的保证,第一个(或任何你挑),实际上是有效的。 这就是为什么它像在教程完成。



Answer 5:

假设你是新的插座,在这一点上。 是的,这是至关重要的,因为使用的getaddrinfo之后,你可以检索进一步验证一个地址信息。



文章来源: Is it necessary to attempt to connect to all addresses returned by getaddrinfo()?