I have searched everywhere but their solution requires some form of IP address.
Here are the solutions i have found.
require 'socket'
#METHOD 1
ip = IPSocket.getaddress(Socket.gethostname)
puts ip
#METHOD 2
host = Socket.gethostname
puts host
#METHOD 3(uses Google's address)
ip = UDPSocket.open {|s| s.connect("64.233.187.99", 1); s.addr.last}
puts ip
#METHOD 4(uses gateway address)
def local_ip
orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true # turn off reverse DNS resolution temporarily
UDPSocket.open do |s|
s.connect '192.168.1.1', 1
s.addr.last
end
ensure
Socket.do_not_reverse_lookup = orig
end
ip=local_ip
puts ip
All of them require IP address of someone. Is there a solution that does not use someone else's IP address? Preferably, platform independent.
Isn't the solution you are looking for just:
require 'socket'
addr_infos = Socket.ip_address_list
Since a machine can have multiple interfaces and multiple IP Addresses, this method returns an array of Addrinfo.
You can fetch the exact IP addresses like this:
addr_infos.each do |addr_info|
puts addr_info.ip_address
end
P.S. The question is a bit old, but shows up as the first item on Google and it doesn't contain the solution most people are looking for, so I decided to post it.
Hope it helps.
require 'socket'
Socket::getaddrinfo(Socket.gethostname,"echo",Socket::AF_INET)[0][3]
quite like method 1, actually
This is what I've been using in production for years:
require 'socket'
require 'resolv-replace'
ip = Socket.ip_address_list.detect{|intf| intf.ipv4_private?}
ip.ip_address
Works great; tested on aws and classical hosting
As there is no such thing as a default ip-interface to a host (there does not need to be any ip-interface at all actually) all assumptions regarding nameing are vague, do not necessarily hold.
The value returned by gethostname()
can be defined independently to any ip-setup, so it does not need to reflect a valid host in terms of a hostname which could be resolved to any ip-address.
From the POSIX system's API's view the only reliabe function to test for the availablily of (ip-)interfaces is the function getifaddrs()
, which returns a list of all interfaces along with their parameters.
As it looks as if Ruby's current Socket lib does not provide an interface to it, this (http://rubygems.org/gems/system-getifaddrs) gem based approach does seem to be the only way to go.
parse the output of the ip
command?
from https://gist.github.com/henriquemenezes/a99f13da957515023e78aea30d6c0a48
gw = `ip route show`[/default.*/][/\d+\.\d+\.\d+\.\d+/]
or parse the output of the ipconfig
command: https://stackoverflow.com/a/12632929/32453