我有一个网段列表,我希望我的网站能够根据用户的 IP 地址识别用户连接到哪个网段。这样我就可以在我的网站上自动选择他们的位置,而不是他们必须手动选择。什么是好的方法或确定这个?
到目前为止,我有以下内容。
查找客户端IP地址:
local_ip = UDPSocket.open {|s| s.connect('64.233.187.99', 1); s.addr.last }
我的网段数组:
network_segments = [
{"name"=>"Site 1", "starting_address"=>"192.168.168.1", "ending_address"=>"192.168.175.254"},
{"name"=>"Site 2", "starting_address"=>"192.168.184.1", "ending_address"=>"192.168.191.254"},
{"name"=>"Site 3", "starting_address"=>"192.168.176.1", "ending_address"=>"192.168.183.254"}
]
我已经尝试从 IP 中删除句点并遍历每个网段以查看 local_ip 是否 > starting_address 和 <ending_address,但这似乎并不准确。它应该只返回一个名称,它会返回所有名称。
有没有更好的方法来查看local_ip是否在我的任何网段IP之间?
ip = local_ip.delete('.').to_i
network_segments.each do |seg|
start_addr = seg['starting_address'].delete('.').to_i
end_addr = seg['ending_address'].delete('.').to_i
if ip > start_addr and ip < end_addr
puts seg['name']
end
end
最佳答案
使用 IPAddr类(表示 IP 地址)而不是删除点的字符串。 IPAddr 提供比较运算符,可以了解哪些地址大于/小于另一个地址。
require 'ipaddr'
# ...
local_ip = IPAddr.new(local_ip)
network_segments.each do |seg|
if local_ip > IPAddr.new(seg['starting_address']) and local_ip < IPAddr.new(seg['ending_address'])
puts seg['name']
end
end
编辑:除了您的范围是 1..254 而不是 0..255 之外,您还可以使用网络掩码范围实现检查,例如:
IPAddr.new("192.168.168.1/21").to_range.first.to_s # => "192.168.168.0"
IPAddr.new("192.168.168.1/21").to_range.last.to_s # => "192.168.175.255"
IPAddr.new("192.168.168.1/21").include?("192.168.170.1") # => true
IPAddr.new("192.168.168.1/21").include?("192.168.176.1") # => false
关于ruby - Ruby根据IP判断用户所在网段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29156878/