【问题标题】:Is there a way to handle getaddrinfo() output with a single loop and IPv6 socket?有没有办法用单个循环和 IPv6 套接字处理 getaddrinfo() 输出?
【发布时间】:2011-03-20 17:38:24
【问题描述】:

我希望能够遍历作为getaddrinfo() 函数结果的列表,并使用该列表的每个元素调用connect(),直到connect() 成功。不幸的是,即使我指定了AI_ALL | AI_V4MAPPED 标志和AF_INET6 系列,结果也是喜忧参半。列表的第一部分包含sockaddr_in6 结构,第二部分包含sockaddr_in 结构,所以我不能将它们与AF_INET6 套接字一起使用。

我知道我可以创建两个套接字。我想知道是否可以只使用AF_INET6 套接字。

这是操作系统:

> uname -a
> Linux debian 2.6.32-5-amd64 #1 SMP Wed Jan 12 03:40:32 UTC 2011 x86_64 GNU/Linux

【问题讨论】:

  • 为什么不能跳过 v4 地址?
  • @Erik: 可能是因为有些主机不支持 ipv6...
  • @Adrien:我理解 OP 只想要 ip6...也许不是。
  • 我正在学习 API,我想编写一个可靠的客户端,它能够连接到使用任一类型套接字的服务器。
  • @kubi: AI_ALL | AI_V4MAPPEDAF_INET6 应该返回所有找到的映射到 IP6 的 IP4 - 确定你没有同时获得 IP4 地址作为 IP6 和 IP4?如果这样做,您仍然可以跳过AF_INET 地址

标签: c linux networking posix


【解决方案1】:

您不必担心您正在创建的是 AF_INET 还是 AF_INET6 套接字。 只需将 getaddrinfo() 调用中的数据传递给 socket() 调用即可。

例如

/* returns -1 on error, or a connected socket descriptor*/
int opensock(const char *hostname, const char *service)
{
    struct addrinfo hint, *host, *res = NULL;
    int tcp_sd = -1, error;

    memset(&hint, '\0', sizeof(hint));
    hint.ai_socktype = SOCK_STREAM;
    hint.ai_family = PF_UNSPEC;
    error = getaddrinfo(hostname, service, &hint, &res);
    if(error){
        syslog(LOG_DEBUG,"getaddrinfo failed. Cant find host %s: %m",hostname);
        return tcp_sd;
    }
    for (host = res; host; host = host->ai_next) {
        tcp_sd = socket(host->ai_family, host->ai_socktype, host->ai_protocol);
        if (tcp_sd < 0) {
            continue;
        }

        if (connect(tcp_sd, host->ai_addr, host->ai_addrlen) < 0) {
            close(tcp_sd);
            tcp_sd = -1;
            continue;
        }

        break;      /* okay we got one */
    }

    freeaddrinfo(res);

    return tcp_sd;
}

【讨论】:

  • 谢谢,我想我想知道的是规范的方法。您是否知道在悲观的情况下多次调用 socket() 是否会导致性能损失,因为它需要内核完成一些工作?
  • 会影响性能。您可以记住套接字系列是否与之前的循环迭代中的相同,并避免在这种情况下关闭和重新打开它。
猜你喜欢
  • 2018-02-23
  • 1970-01-01
  • 1970-01-01
  • 2018-02-04
  • 2017-01-09
  • 1970-01-01
  • 2012-02-03
  • 1970-01-01
  • 2013-09-03
相关资源
最近更新 更多