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

eve*_*ina 7 c++ gcc ipv4 ipv6 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;
};
Run Code Online (Sandbox Code Playgroud)

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

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

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

πάν*_*ῥεῖ 9

第一个回答所述,自GCC 4.6.4起可获得128位整数支持.

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

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


至于你的编辑:

你不必重新发明轮子!已经有适当的struct定义可以AF_xxx正确地考虑家庭类型.

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

我们有一个IpAddr生产类,它使用opaque sockaddr_in*sockaddr_in6*指针来封装基于sockaddr*指针的IPv4或IPv6地址,并reinterpret_cast<>基于sa_family结构的成员.


Col*_*mbo 4

根据这个线程 __int128_t,并__uint128_t在 4.2 版本左右引入。根据 GCC 的文档,自GCC 4.6.4起支持__int128其未签名的对应版本。unsigned __int128

请注意,不可移植的 128 位整数绝对不是保存和使用 IPv6 地址的合适类型。正如评论中提到的,有专门的数据结构,例如sockaddr_in6.