为什么Ruby的IPaddr#family方法在IPv4地址上调用时返回2,而在IPv6上调用时返回10?

时间:2014-07-28 14:00:17

标签: ruby

使用stdlib中的IPAddr:

IPAddr.new('192.168.0.1').family
=> 2

IPAddr.new('1a03:a240:0100:0000:0000:0000:0000:0000').family
=> 10

所以我猜测2代表IPv4,10代表IPv6。为什么2和10?为什么不是4和6?

使用2和10是没有意义的,因为它意味着IPv4是二进制的,而IPv6是基础10,实际上它们都是二进制的(在引擎盖下),以及人类可读的IPv4形式是基数10而对于IPv6则是十六进制......

是否有一些我不了解的更深层次的逻辑?

4 个答案:

答案 0 :(得分:2)

这些是POSIX套接字地址系列,如sys / socket.h中所定义(例如,参见here)。这包括各种各样的东西,如IPX,appletalk,unix域套接字等。它们只是按顺序编号,因此IPv6具有更大的数字

虽然给IPv4标识符4和IPv6标识符6似乎很自然,但这些可能是唯一具有这种明显映射的两个,而最初的IPv4只是IP

答案 1 :(得分:2)

这个数字是Socket模块中定义的常量。 IPv4地址系列为Socket::AF_INET,IPv6为Socket::AF_INET6

让我感到惊讶的是,在我的Ruby(2.0)上,AF_INET6的数量与你的不同:

[9] pry(main)> IPAddr.new('1a03:a240:0100:0000:0000:0000:0000:0000').family
=> 30
[10] pry(main)> Socket::AF_INET6
=> 30
[11] pry(main)> Socket::AF_INET
=> 2

所以最好不要使用数字本身,而是使用常量名称。

答案 2 :(得分:1)

这不是红宝石做出的决定。它与linux's code base中的宏使用的值相同。我相信保持两个常数同步非常重要。另外我认为常量被逐渐添加到地址族列表中,因此在选择AF_INET6的值时,没有人真正期望AF_INET。然后改变AF_INET的值(同时6已被占用)是迟到的。

答案 3 :(得分:1)

它们的价值为Socket::AF_INETSocket::AF_INET6

>> Socket::AF_INET
=> 2
>> Socket::AF_INET6
=> 10

它们来自与套接字相关的头文件。例如,在我的ubuntu框中:

$ grep PF_INET */*/*.h
i386-linux-gnu/bits/socket.h:#define    PF_INET         2       /* IP protocol family.  */
i386-linux-gnu/bits/socket.h:#define    PF_INET6        10      /* IP version 6.  */
i386-linux-gnu/bits/socket.h:#define    AF_INET         PF_INET
i386-linux-gnu/bits/socket.h:#define    AF_INET6        PF_INET6