Question

Je suis en train de maintenir une application Ruby on Rails et je recherche un moyen simple de trouver le nom d'hôte ou l'adresse IP de la box sur laquelle je me trouve (puisqu'il s'agit d'une VM et que les nouvelles instances peuvent avoir des noms d'hôte ou des adresses IP différents) .Existe-t-il un moyen simple et rapide de le faire dans Ruby on Rails ?

Modifier:La réponse ci-dessous est correcte mais la clarification fournie par Craig est utile (voir également le lien fourni dans la réponse) :

Le code [ci-dessous] ne fait pas de connexion ni n'envoie de paquets (au 64.233.187.99 qui est Google).Étant donné que UDP est un protocole sans état Connect () fait simplement un appel système qui comprend comment acheminer les paquets en fonction de l'adresse et de l'interface (et donc de l'adresse IP), il devrait se lier.addr () renvoie un tableau contenant la famille (AF_INET), le port local et l'adresse locale (ce que nous voulons) de la prise.

Était-ce utile?

La solution

Depuis 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"

Autres conseils

Nom d'hôte

Un moyen simple d’obtenir simplement le nom d’hôte dans Ruby est :

require 'socket'
hostname = Socket.gethostname

Le problème est que cela dépend de l'hôte connaissant son propre nom car il utilise soit le gethostname ou uname appel système, donc cela ne fonctionnera pas pour le problème d’origine.

Fonctionnellement, c'est identique au hostname réponse, sans faire appel à un programme externe.Le nom d'hôte peut être complet ou non, selon la configuration de la machine.


Adresse IP

Depuis Ruby 1.9, vous pouvez également utiliser la bibliothèque Socket pour obtenir une liste d'adresses locales. ip_address_list renvoie un tableau de AdresseInfo objets.La façon dont vous choisirez dépendra de ce que vous voulez faire et du nombre d'interfaces dont vous disposez, mais voici un exemple qui sélectionne simplement la première adresse IP IPV4 sans bouclage sous forme de chaîne :

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

Essaye ça:

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

Un serveur possède généralement plusieurs interfaces, au moins une privée et une publique.

Puisque toutes les réponses ici traitent de ce scénario simple, une méthode plus simple consiste à demander à Socket le numéro actuel. ip_address_list() un péché:

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

Les deux renvoient un objet Addrinfo, donc si vous avez besoin d'une chaîne, vous pouvez utiliser le ip_address() méthode, comme dans :

ip= my_first_public_ipv4.ip_address unless my_first_public_ipv4.nil?

Vous pouvez facilement trouver la solution la plus adaptée à votre cas en modifiant les méthodes Addrinfo utilisées pour filtrer l'adresse d'interface requise.

Cette adresse IP utilisée ici est celle de Google, mais vous pouvez utiliser n'importe quelle IP accessible.

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

Le plus simple est host_with_port dans le contrôleur.rb

host_port= request.host_with_port

La réponse acceptée fonctionne mais vous devez créer un socket pour chaque requête et cela ne fonctionne pas si le serveur est sur un réseau local et/ou n'est pas connecté à Internet.Je pense que le ci-dessous fonctionnera toujours puisqu'il analyse l'en-tête de la requête.

request.env["SERVER_ADDR"]

Mettez la partie en surbrillance entre backticks :

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

Ou juste request.host si vous ne vous souciez pas de savoir si c'est une adresse IP ou non.

Semblable à la réponse en utilisant hostname, en utilisant l'externe uname commande sous UNIX/LINUX :

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

Pour les adresses IP utilisées (votre machine pourrait avoir plusieurs interfaces réseau), vous pouvez utiliser quelque chose comme ceci:

 # 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']

Vous vous retrouverez probablement avec plusieurs adresses IP sur chaque machine (127.0.0.1, 192.168.0.1, etc.).Si vous utilisez *NIX comme système d'exploitation, je vous suggère d'utiliser hostname, puis exécutez une recherche DNS à ce sujet.Vous devriez pouvoir utiliser /etc/hosts pour définir le nom d'hôte local à résoudre en adresse IP de cette machine.Il existe des fonctionnalités similaires sous Windows, mais je ne les ai pas utilisées car Windows 95 était à la pointe de la technologie.

L'autre option serait d'utiliser un service de recherche comme WhatIsMyIp.com.Ces gars-là vous renverront votre adresse IP réelle.C'est également quelque chose que vous pouvez facilement configurer avec un script Perl sur un serveur local si vous préférez.Je pense qu'environ 3 lignes de code pour afficher l'adresse IP distante de %ENV devraient vous couvrir.

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}\ /)

Les quelques réponses avec require 'socket' ça a l'air bien.Ceux avec request.blah_blah_blah supposent que vous utilisez des rails.

IO doit être disponible à tout moment.Le seul problème avec ce script serait que si ifconfig est affiché d'une manière différente sur vos systèmes, vous obtiendrez alors des résultats différents pour l'IP.La recherche du nom d'hôte doit être solide comme Sears.

essayer: Demande.remote_ip

ip_distant()

Déterminez l’adresse IP d’origine.Remote_addr est la norme mais échouera si l'utilisateur est derrière un proxy.Http_client_ip et / ou http_x_forwarded_for sont définis par des proxys, alors vérifiez-les si Remote_addr est un proxy.Http_x_forwarded_for peut être une liste de virgule dans le cas de plusieurs procurations enchaînées;La dernière adresse qui n'est pas fiable est l'IP d'origine.

Mise à jour:Oups, désolé, j'ai mal lu la documentation.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top