如果我们使用 32 位整数来存储 IPv4 地址,那么必须考虑整数的字节顺序。
但是,由于几乎所有平台下都没有内置的 128 位整数类型,因此 IPv6 地址必须存储到字节数组中,所以,我认为字节顺序不再是问题。
我对么?或者 IPv6 有对应的函数 htonlXXX 吗?
IPv6 确实需要 ipv6 地址的网络字节顺序。hton 和 ntoh 都是关于将地址从您在代码中存储的方式转换为需要在数据包中存储的方式(反之亦然)。所以问题就变成了如何将它存储在代码中。
此外,在代码中定义 IPv6 地址可以允许更多的方式来解决它,而不仅仅是一个字节数组:
struct in6_addr
{
union
{
__u8 u6_addr8[16];
__u16 u6_addr16[8];
__u32 u6_addr32[4];
} in6_u;
#define s6_addr in6_u.u6_addr8
#define s6_addr16 in6_u.u6_addr16
#define s6_addr32 in6_u.u6_addr32
};
对于用户,IPv6 地址表示为 8 个 16 位值。如果您在代码中将地址存储为 8 个 16 位值,那么您需要在使用 u6_addr16[] 数组将其放入数据包时对每个 16 位值使用 htons,并在检索每个 16 位值时使用 ntohs - 来自 u6_addr16[] 的位值。
这些链接很有帮助:
http://msdn.microsoft.com/en-us/library/ee175867.aspx
http://en.wikipedia.org/wiki/IPv6_address(尤其是右上角的图表)
网络字节排序在 2 种情况下很有用。首先,您可以在您所说的地址上使用它。其次,您必须考虑发送数据的字节顺序。您在评论中说 TCP 只是一个字节流是对的,但是许多协议将数字的字节顺序规定为网络顺序。
但是,由于几乎所有平台下都没有内置的 128 位整数类型,因此 IPv6 地址必须存储到字节数组中,所以,我认为字节顺序不再是问题。
这不符合; 在构造字节数组的时候,还是要考虑是按0123456789ABCDEF还是FEDCBA976543210的顺序打包数据。仍然需要正确的字节顺序,只是诸如ntohl()
和之类的功能htonl()
不适用于生成 128 位地址。
例如,如果您使用inet_ntop()从“表示”形式生成二进制地址,则您不需要自己考虑任一地址类型的字节顺序。字节顺序仍然很重要,但 API 会为您处理。
在处理 IPv4 地址和端口号时必须密切注意字节顺序的具体原因是结构sockaddr_in
和in_addr
数据成员的整数类型大于char
,并且其内容要求按网络字节顺序排列。
即使使用 IPv4,您也可以避免担心地址部分的字节顺序——使用inet_aton
或直接从字符串inet_pton
中填充。in_addr
后一个函数也处理 IPv6 地址(填充一个in6_addr
)。
使用 IPv6 时,您仍然需要htons
端口号,如果您选择访问in6_addr
大于字节的块,则需要进行主机/网络转换。
正如您所说,如果您的平台没有 128 位类型,那么您无法像访问单个 32 位块那样访问in6_addr
单个 128in_addr
位块。但是,如果某些具有 128 位类型的网络接口/实现确实决定公开它的 128 位视图,那么希望它也能提供匹配ntohX
和htonX
功能。
struct in6_addr{
uint8_t s6_addr[16];//128bit ipv6 address
};
通过这个结构,你认为是对的。