Получение имени хоста или IP в Ruby on Rails


Я нахожусь в процессе поддержки приложения Ruby on Rails и ищу простой способ найти имя хоста или IP-адрес окна, в котором я нахожусь (поскольку это виртуальная машина, и новые экземпляры могут иметь разные имена хостов или IP-адреса). Есть ли быстрый и простой способ сделать это в Ruby on Rails?

Edit: ответ ниже Правильный, но разъяснение Крейга полезно (см. Также предоставленную ссылку в ответе):

код [ниже] не делает a соединение или отправить любые пакеты (в 64.233.187.99 который является google). Поскольку UDP-это протокол без состояния подключения() просто делает системный вызов, который выясняет, как маршрутизировать пакеты на основании адреса и чего интерфейс (и, следовательно, IP-адрес) он должен привязать к себе. адрес() возвращает массив, содержащий семейство (AF_INET), локальный порт и локальный адрес (который это то, что мы хотим) сокета.

12 75

12 ответов:

от coderrr.wordpress.com:

require 'socket'

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 '64.233.187.99', 1
    s.addr.last
  end
ensure
  Socket.do_not_reverse_lookup = orig
end

# irb:0> local_ip
# => "192.168.0.127"

Хоста

простой способ просто получить имя хоста в Ruby:

require 'socket'
hostname = Socket.gethostname

загвоздка в том, что это зависит от того, что хост знает свое собственное имя, потому что он использует либо gethostname или uname системный вызов, поэтому он не будет работать для исходной задачи.

функционально это идентичные hostname ответьте, не вызывая внешнюю программу. Имя хоста может быть или не быть полным, в зависимости от компьютера конфигурация.


IP-адрес

начиная с ruby 1.9, вы также можете использовать библиотеку сокетов для получения списка локальных адресов. ip_address_list возвращает массив AddrInfo объекты. Как вы выбираете из него будет зависеть от того, что вы хотите сделать и сколько интерфейсов у вас есть, но вот пример, который просто выбирает первый IP-адрес IPV4 без замыкания на себя в виде строки:

require 'socket'
ip_address = Socket.ip_address_list.find { |ai| ai.ipv4? && !ai.ipv4_loopback? }.ip_address

попробуйте это:

host = `hostname`.strip # Get the hostname from the shell and removing trailing \n
puts host               # Output the hostname

сервер обычно имеет более одного интерфейса, по крайней мере, одна частная и одна государственная.

поскольку все ответы здесь касаются этого простого сценария, более чистый способ-попросить сокет для текущего ip_address_list() в:

require 'socket'

def my_first_private_ipv4
  Socket.ip_address_list.detect{|intf| intf.ipv4_private?}
end

def my_first_public_ipv4
  Socket.ip_address_list.detect{|intf| intf.ipv4? and !intf.ipv4_loopback? and !intf.ipv4_multicast? and !intf.ipv4_private?}
end

оба возвращают объект Addrinfo, поэтому, если вам нужна строка, вы можете использовать ip_address() способ, как в:

ip= my_first_public_ipv4.ip_address unless my_first_public_ipv4.nil?

вы можете легко разработать более подходящее решение для вашего случая, изменив методы Addrinfo, используемые для фильтрации требуемый адрес интерфейса.

этот IP-адрес, используемый здесь, является Google, но вы можете использовать любой доступный IP.

require "socket"
local_ip = UDPSocket.open {|s| s.connect("64.233.187.99", 1); s.addr.last}

самый простой это host_with_port в контроллер.РБ

host_port= request.host_with_port

принятый ответ работает, но вы должны создать сокет для каждого запроса, и это не работает, если сервер находится в локальной сети и/или не подключен к интернету. Ниже, я считаю, всегда будет работать, так как он анализирует заголовок запроса.

request.env["SERVER_ADDR"]

поместите выделенную часть в backticks:

`dig #{request.host} +short`.strip # dig gives a newline at the end

или просто request.host Если вам все равно, является ли это IP или нет.

похоже на ответ с помощью hostname, используя внешнюю uname команда на UNIX / LINUX:

hostname = `uname -n`.chomp.sub(/\..*/,'')  # stripping off "\n" and the network name if present

для IP-адреса (ваша машина может иметь несколько сетевых интерфейсов), вы могли бы использовать что-то вроде этого:

 # on a Mac:
 ip_addresses = `ifconfig | grep 'inet ' | grep -v 127.0.0.1 | cut -d' ' -f 2`.split
 => ['10.2.21.122','10.8.122.12']

 # on Linux:
 ip_addresses = `ifconfig -a | grep 'inet ' | grep -v 127.0.0.1 | cut -d':' -f 2 | cut -d' ' -f 1`.split
 => ['10.2.21.122','10.8.122.12']

вы, вероятно, окажетесь с несколькими IP-адресами на каждой машине (127.0.0.1, 192.168.0.1 и т. д.). Если вы используете *NIX в качестве ОС, я бы предложил использовать hostname, а затем запуск DNS-поиска на это. Вы должны иметь возможность использовать /etc / hosts для определения локального имени хоста для разрешения на IP-адрес для этой машины. В Windows есть аналогичная функциональность, но я не использовал ее, так как Windows 95 была кровоточащим краем.

другой вариант-нажать на поиск обслуживание как WhatIsMyIp.com. Эти ребята вернут вам ваш реальный IP-адрес. Это также то, что вы можете легко настроить с помощью Perl скрипта на локальном сервере, если вы предпочитаете. Я считаю, что 3 строки или около того кода для вывода удаленного IP из %ENV должны охватывать вас.

io = IO.popen('hostname')
hostname = io.readlines

io = IO.popen('ifconfig')
ifconfig = io.readlines
ip = ifconfig[11].scan(/\ \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\ /)

пара ответов с require 'socket' выглядеть хорошо. Те, что с просьбой.blah_blah_blah предположим, что вы используете рельсы.

IO должен быть доступен все время. Единственная проблема с этим скриптом, если ifconfig выводится в другом поместье на ваших системах, тогда вы получите разные результаты для IP. Имя хоста должно быть твердым, как Sears.

попробуй: запрос.remote_ip

remote_ip ()

определить исходный IP-адрес. REMOTE_ADDR является стандартным, но будет неудачно, если пользователь находится за прокси. Как настроен и/или HTTP_X_FORWARDED_FOR задаются прокси, поэтому проверьте их, если REMOTE_ADDR-это прокси. HTTP_X_FORWARDED_FOR может быть разделен запятыми список в случае нескольких цепных прокси; Последний адрес, который не является доверенным является источником ИНТЕЛЛЕКТУАЛЬНАЯ СОБСТВЕННОСТЬ.

обновление: Ой, извините, что я неправильно прочитал документацию.