[ruby] Ruby on Rails에서 호스트 이름 또는 IP 가져 오기

Ruby on Rails 앱을 유지 관리하는 중이며 현재 사용중인 상자의 호스트 이름 또는 IP 주소를 쉽게 찾을 수있는 방법을 찾고 있습니다 (VM이므로 새 인스턴스에는 다른 호스트 이름 또는 IP 주소가있을 수 있음). . Ruby on Rails에서이 작업을 수행하는 빠르고 쉬운 방법이 있습니까?

편집 : 아래 답변은 정확하지만 Craig가 제공 한 설명이 유용합니다 (답변에 제공된 링크 참조).

[아래] 코드는 연결하거나 패킷을 보내지 않습니다 (google 인 64.233.187.99로). UDP는 상태 비 저장 프로토콜이기 때문에 connect ()는 주소를 기반으로 패킷을 라우팅하는 방법과 바인딩해야하는 인터페이스 (따라서 IP 주소)를 파악하는 시스템 호출을 수행 할뿐입니다. addr ()은 소켓의 패밀리 (AF_INET), 로컬 포트 ​​및 로컬 주소 (원하는 것)를 포함하는 배열을 반환합니다.



답변

에서 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 주소

루비 1.9부터 소켓 라이브러리를 사용하여 로컬 주소 목록을 가져올 수도 있습니다. AddrInfo 객체 ip_address_list의 배열을 반환 합니다. 선택 방법은 수행하려는 작업과 보유한 인터페이스 수에 따라 다르지만, 다음은 첫 번째 비 루프백 IPV4 IP 주소를 문자열로 선택하는 예입니다.

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_portcontroller.rb입니다.

host_port= request.host_with_port


답변

수락 된 답변은 작동하지만 모든 요청에 ​​대해 소켓을 만들어야하며 서버가 로컬 네트워크에 있거나 인터넷에 연결되어 있지 않으면 작동하지 않습니다. 아래는 요청 헤더를 구문 분석하기 때문에 항상 작동한다고 생각합니다.

request.env["SERVER_ADDR"]