我正在开发一个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)以及是否存在任何已知错误。此外,上述哪种解决方案可能是最方便的解决方案?
答案 0 :(得分:9)
正如1st answer 128位整数支持中所述,自GCC 4.6.4起可用。
您的问题不是128位整数支持,而是 如何正确表示IPv6地址 。
对此的正确答案是使用socket API中提供的struct
定义。
这些可用于IPv6堆栈的各种操作系统实现并标准化 此外,您不必担心使用这些效率。对齐打包将正常工作,您不必关心实际表示的字节顺序与网络字节顺序问题。
至于你的编辑:
您不必重新发明轮子!已经有适当的struct
定义可以正确尊重AF_xxx
家庭类型。
请查看这些资源以获取更详细的说明:
sys/socket.h
- main sockets header netinet/in.h
- Internet address family 我们在生产中有一个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 __int128
自GCC 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