【问题标题】:How to determine IP version in C++?如何在 C++ 中确定 IP 版本?
【发布时间】:2014-03-07 15:24:12
【问题描述】:

我想同时支持 IPv4 和 IPv6 版本。现在。我只支持 IPv4,但为了为每个版本的 IP 设置不同的行为,我需要知道我正在使用的 IP 版本。

目前我正在使用gethostbyname 函数,并根据hostent structh_addrtype 字段设置它是IPv4 还是IPv6,但我想知道这真的正确吗?如果不是,有什么可能的方法来获得 IP 版本?如果它是正确的,如果这个功能失败了我该怎么办?

提前致谢。

【问题讨论】:

    标签: c++ sockets ipv6


    【解决方案1】:

    gethostbyname 已弃用,您实际上应该使用 getaddrinfo,它被弃用的原因之一是 IPv4/IPv6 问题。

    话虽如此,是的,检查h_addrtype 是正确的。

    【讨论】:

      【解决方案2】:

      IPv6 地址的h_addrtype 字段应为AF_INET6(而不是AF_INET),并且在使用gethostbyname 时测试该字段是正确的方法。

      但是,您应该考虑在新应用程序中使用 getaddrinfo 而不是 gethostbyname

      【讨论】:

      • 我想知道他在使用getaddrinfo(也许sockaddr_storage)时是否需要担心v4/v6的差异
      • @nodakai 这是一个公平的观点——理论上如果你使用getaddrinfo,无论主机是在 IPv4 还是 IPv6 上,代码都会“正常工作”。
      • 我怀疑理论往往与实践不同? =)
      • 是的,理论上它们是一样的,但实际上它们不是 ;-)
      【解决方案3】:

      您可以使用getsockname来确定IP版本,

      int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
      

      可以采用以下方法,

      /* Function to detect family of a socket */
      // Return AF_INET or AF_INET6
      unsigned short GetSocketFamily(int sockfd)
      {
          unsigned short sa[16];  // 32 bytes is enough for sockaddr version for any family
                                  // 16 bytes for IPv4 and 28 bytes for IPv6
          socklen_t lth = sizeof(sa);
          getsockname(sockfd, (struct sockaddr *)&sa, &lth);
          return sa[0]; // In any case (IPv4 or IPv6) family is the first halfword of 
                        // address structure
      }
      

      【讨论】:

      • 据我了解,对于您的方法,我已经需要一个开放的套接字,这在我的情况下是不可接受的。
      猜你喜欢
      • 2013-12-08
      • 2018-05-17
      • 1970-01-01
      • 1970-01-01
      • 2012-04-21
      • 2015-07-15
      • 2017-03-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多