从ruby Socket.ip_address_list识别所有相关的IP地址

问题描述 投票:1回答:1

[当使用ruby Socket.ip_address_list时,它将返回一个addr_info(https://ruby-doc.org/stdlib-2.0.0/libdoc/socket/rdoc/Addrinfo.html)的数组

示例:

require 'socket'

addr_infos = Socket.ip_address_list

此数组可以由所有定义的ip_addresses和属性迭代和列出,例如

addr_infos.each do |addr_info|
  puts "#{addr_info.ip_address} 
         #{addr_info.ipv4? ? 'ipv4? ' : ''}" + 
        "#{addr_info.ipv4_loopback? ? 'ipv4_loopback? ' : ''}" +
        "#{addr_info.ipv4_private? ? 'ipv4_private? ' : ''}" +
        "#{addr_info.ipv4_multicast? ? 'ipv4_multicast? ' : ''}" +
        "#{addr_info.ipv6? ? 'ipv6? ' : '' }" +
        "#{addr_info.ipv6_loopback? ? 'ipv6_loopback? ' : ''}" +
        "#{addr_info.ipv6_linklocal? ? 'ipv6_linklocal? ' : ''}" +
        "#{addr_info.ipv6_multicast? ? 'ipv6_multicast? ' : ''}" +
        "#{addr_info.ipv6_sitelocal? ? 'ipv6_sitelocal? ' : ''}" +
        "#{addr_info.ipv6_unique_local? ? 'ipv6_unique_local? ' : ''}" +
        "#{addr_info.ipv6_mc_global? ? 'ipv6_mc_global? ' : ''}" +
        "#{addr_info.ipv6_unspecified? ? 'ipv6_unspecified? ' : ''}"
end

结果看起来像

127.0.0.1
       ipv4? ipv4_loopback? 
192.168.178.33
       ipv4? ipv4_private? 
1.2.4.5
       ipv4?
::1
       ipv6? ipv6_loopback?
fe80::1%lo0
       ipv6? ipv6_linklocal? 
fe80::aede:48ff:fe00:1122%en5
       ipv6? ipv6_linklocal? 
fe80::68:e785:4cfb:41e6%en0
       ipv6? ipv6_linklocal? 
fe80::50fc:46ff:fe4c:c2b4%awdl0
       ipv6? ipv6_linklocal? 
fe80::3203:d609:ff08:151d%utun0
       ipv6? ipv6_linklocal?
fd00::ffff:aaaa:bbbb:7005
       ipv6? ipv6_unique_local?
2003:ffff:4723:aaaa:bbbb:8888:269a:42a4
       ipv6?

Q:如何识别“正确”的IP地址以将侦听服务绑定到?

恕我直言,很容易识别IPv4地址,例如:

IPv4 = ipv4? && (ipv4_loopback? || ipv4_private? || !(ipv4_loopback? || ipv4_private? || ipv4_multicast?))

但是如果有那么多ipv6_?属性,我想知道如何检查以识别IPv6地址。

这是正确的建议吗?

在以下情况下为IPv6地址:

a。 ipv6?是真的,没有其他ipv6 _...?属性为trueb。 ipv6?和ipv6_loopback?是真的C。 ipv6?和ipv6_unique_local为true

我是否错过了IPv6地址的某些内容?

ruby sockets ip-address
1个回答
0
投票

除此问题外,这是我目前的解决方案。也许有些人可以添加评论或投票,以确保这是正确的方向

ip_addresses_for_host = []
Socket.ip_address_list.each do |a|
# test for all local valid ipv4 and ipv6 ip_addresses
# check question on stackoverflow for details
# https://stackoverflow.com/questions/59770803/identify-all-relevant-ip-addresses-from-ruby-socket-ip-address-list
ip_addresses_for_host << a.ip_address if \
  (a.ipv4? &&
    (a.ipv4_loopback? || a.ipv4_private? ||
     !(a.ipv4_loopback? || a.ipv4_private? || a.ipv4_multicast?)
    )
  ) ||
  (a.ipv6? &&
    (a.ipv6_loopback? || a.ipv6_unique_local? ||
     !(a.ipv6_loopback? || a.ipv6_unique_local? || a.ipv6_linklocal? || a.ipv6_multicast? || a.ipv6_sitelocal? ||
       a.ipv6_mc_global? || a.ipv6_mc_linklocal? || a.ipv6_mc_nodelocal? || a.ipv6_mc_orglocal? || a.ipv6_mc_sitelocal? ||
       a.ipv6_v4compat? || a.ipv6_v4mapped? || a.ipv6_unspecified?)
    )
  )
end

这将解决IPv4:

a。 127.0.0.1b。私有地址,例如192.168./16、10/8 / ...C。其他ipv4地址,例如1.2.3.4

并且对于IPv6:

a。 :: 1b。 fc00 ::C。 abcd ::

知道有人会增加更多知识。

© www.soinside.com 2019 - 2024. All rights reserved.