【问题标题】:What is the correct way to determine which sockaddr variant to use?确定使用哪个 sockaddr 变体的正确方法是什么?
【发布时间】:2014-04-09 20:39:08
【问题描述】:

我想知道确定使用哪个 sockaddr 变体的正确方法。

来自Beej's Guide to Network Programming

if (p->ai_family == AF_INET) { // IPv4
    struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
    addr = &(ipv4->sin_addr);
    ipver = "IPv4";
} else { // IPv6
    struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr;
    addr = &(ipv6->sin6_addr);
    ipver = "IPv6";
}

他在这里检查地址族是否为AF_INET,如果是则使用sockaddr_in。如果不是,他正在使用sockaddr_in6。那不是不安全吗?如果它是不是 IPv6 的其他地址族怎么办?

是否有一种认可的标准方法来确定哪个结构映射到相应的地址族?

【问题讨论】:

    标签: c sockets networking


    【解决方案1】:

    为了安全起见,您可以对 AF_INET6 使用 else if 并使用最终的 else 来失败,因为地址系列不受支持。我会避免尝试为其他家庭提供支持,除非您有实际需求来支持他们。在YAGNI 之后,如果您没有计划支持或测试规范,那么按照规范编写代码是不明智的。

    if (p->ai_family == AF_INET) { // IPv4
        struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
        addr = &(ipv4->sin_addr);
        ipver = "IPv4";
    } else if (p->ai_family == AF_INET6) { // IPv6
        struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr;
        addr = &(ipv6->sin6_addr);
        ipver = "IPv6";
    } else {
        // UNSUPPORTED! FAIL! FAIL!
    }
    

    【讨论】:

    • 在我的情况下,即使是不熟悉的地址系列,我也需要通过电话。在这些情况下,我会忽略数据并将其复制为 void 指针。为什么它首先不是空指针让我感到困惑,但我猜它只是遗留代码。
    • 另外,我建议使用sockaddr_storageHere's为什么
    猜你喜欢
    • 1970-01-01
    • 2018-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-24
    • 2021-09-23
    • 2017-04-07
    相关资源
    最近更新 更多