存储IPv4 / IPv6地址的有效方法

时间:2014-10-23 15:21:43

标签: c++ gcc ipv6 ipv4 int128

我正在开发一个C / C ++网络项目,它应该能够使用IPv4和IPv6网络堆栈。 该项目仅适用于Linux。 因此,我试图找到一种有效的方法来存储IP地址并区分协议系列。 第一种方法是建立一个联盟:

struct ip_addr {
   uint8_t fam; // socket family type
   union {
       struct in_addr ipv4_sin_addr;
       struct in6_addr ipv6_sin_addr;
   }addr;
};

第二种方法是定义一个typedef std::vector<unsigned char> IPAddressNumber并在向量的字节数之后产生差异。

第三种方法是使用gcc中的int128_t / uint128_t或__int128_t。

对于最后一种情况,我想知道哪些版本的GCC支持这些类型,适用于哪些平台(尤其是IA-32 / IA-64)以及是否存在任何已知错误。此外,上述哪种解决方案可能是最方便的解决方案?

3 个答案:

答案 0 :(得分:9)

正如1st answer 128位整数支持中所述,自GCC 4.6.4起可用。

您的问题不是128位整数支持,而是 如何正确表示IPv6地址
对此的正确答案是使用socket API中提供的struct定义。

这些可用于IPv6堆栈的各种操作系统实现并标准化 此外,您不必担心使用这些效率。对齐打包将正常工作,您不必关心实际表示的字节顺序与网络字节顺序问题。


至于你的编辑:

您不必重新发明轮子!已经有适当的struct定义可以正确尊重AF_xxx家庭类型。

请查看这些资源以获取更详细的说明:

我们在生产中有一个IpAddr类,它使用不透明的sockaddr_in*sockaddr_in6*指针来封装基于sockaddr*指针的IPv4或IPv6地址,以及reinterpret_cast<>基于结构的sa_family成员。

答案 1 :(得分:3)

根据this thread __int128_t__uint128_t在版本4.2附近引入。根据GCC的文档__int128及其未签署的对应unsigned __int128GCC 4.6.4起受支持。

请注意,不可移植的128位整数绝对是保存和使用IPv6地址的适当类型。正如评论中所提到的,有一些特殊的数据结构,如sockaddr_in6

答案 2 :(得分:0)

此代码来自nginx。与第一个答案相同。 我认为使用指针sockaddr_in *不是一个好主意。

GridView

https://github.com/nginx/nginx/blob/912fb44e25c6ab2598e36b4544c709b871251b2e/src/core/ngx_inet.h#L44