Trouver des adresses IP à l'aide de Python stdlib
Comment puis-je trouver des adresses IP locales (c'est à dire 192.168.x.x ou 10.0.x.x) en Python plate-forme de manière indépendante et en utilisant uniquement la bibliothèque standard?
L'adresse IP locale? Ou IP publique? Comment allez-vous traiter avec les systèmes avec de multiples adresses ip?
utilisation
C'est une mauvaise idée. Tout d'abord, vous êtes inutilement la fourche d'un nouveau processus, et qui peut empêcher votre programme de travail dans bien verrouillé configurations (ou, vous aurez à laisser les droits de votre programme n'a pas besoin). Ensuite, vous aurez introduire des bogues pour les utilisateurs de différents paramètres régionaux. Troisièmement, si vous décidez de commencer un nouveau programme à tous, vous ne devriez pas commencer une déconseillé d'une
vous avez absolument raison, merci pour la correction de ma bêtise
Un problème plus fondamental ici est que, dans un écrit correctement moderne programme de mise en réseau la droite (ensemble de) adresse IP locale(es) dépend des pairs, ou de l'ensemble du potentiel des pairs. Si l'adresse IP locale est nécessaire pour
utilisation
ifconfig -a
et l'utilisation de la sortie à partir de là...C'est une mauvaise idée. Tout d'abord, vous êtes inutilement la fourche d'un nouveau processus, et qui peut empêcher votre programme de travail dans bien verrouillé configurations (ou, vous aurez à laisser les droits de votre programme n'a pas besoin). Ensuite, vous aurez introduire des bogues pour les utilisateurs de différents paramètres régionaux. Troisièmement, si vous décidez de commencer un nouveau programme à tous, vous ne devriez pas commencer une déconseillé d'une
ip addr
est beaucoup plus approprié (et plus facile à analyser, le démarrage).vous avez absolument raison, merci pour la correction de ma bêtise
Un problème plus fondamental ici est que, dans un écrit correctement moderne programme de mise en réseau la droite (ensemble de) adresse IP locale(es) dépend des pairs, ou de l'ensemble du potentiel des pairs. Si l'adresse IP locale est nécessaire pour
bind
un socket à une interface particulière, c'est une question de politique. Si l'adresse IP locale est nécessaire de le remettre à un de ses pairs, de sorte que les pairs peuvent "call back", c'est à dire d'ouvrir une connexion à l'ordinateur local, puis la situation dépend de s'il y a des NAT (Traduction d'Adresse Réseau) cases entre les deux. Si il n'y a pas NATs, getsockname
est un bon choix.OriginalL'auteur UnkwnTech | 2008-10-03
Vous devez vous connecter pour publier un commentaire.
Cela ne fonctionne pas toujours (renvoie
127.0.0.1
sur des machines ayant le nom d'hôte dans/etc/hosts
comme127.0.0.1
), un accompagnement serait ce que gimel montre, l'utilisationsocket.getfqdn()
à la place. Bien sûr, votre machine a besoin d'un nom d'hôte peut être résolu.Une variante: socket.gethostbyname(socket.getfqdn())
Il semble que ce retour à une seule adresse IP. Que faire si la machine dispose de plusieurs adresses?
Sur Ubuntu il renvoie 127.0.1.1 pour une raison quelconque.
R. Combes, utilisez le code suivant pour récupérer la liste des adresses IPv4 qui appartiennent à la machine hôte:
socket.gethostbyname_ex(socket.gethostname())[-1]
OriginalL'auteur Vinko Vrsalovic
Je viens de trouver cela, mais il semble un peu hackish, cependant, disent-ils essayé sur *nix et je l'ai fait sur windows et ça a fonctionné.
Cela suppose que vous avez un accès à internet, et qu'il n'y a pas de proxy local.
Il pourrait être une bonne idée d'attraper socket.erreur exceptions qui peuvent être ressuscité par s.connect()!
Il serait préférable d'utiliser l'adresse IP plutôt qu'un nom de domaine, il doit être plus rapide et indépendant de la disponibilité du DNS. E. g. nous pouvons utiliser 8.8.8.8 IP: Google public DNS server.
Bon, cette méthode fonctionne très bien sur Linux et Windows
Très intelligent, fonctionne parfaitement. Au lieu de gmail ou 8.8.8.8, vous pouvez également utiliser l'adresse IP ou l'adresse du serveur que vous voulez être vu à partir de, si cela est applicable.
OriginalL'auteur UnkwnTech
Cette méthode renvoie le "la primaire" la propriété intellectuelle sur la zone locale (l'un avec une route par défaut).
Python 2 ou 3:
Cela renvoie une adresse IP unique qui est le principal (l'un avec une route par défaut). Si vous avez besoin de la place, de la propriété intellectuelle attachés à toutes les interfaces (y compris localhost, etc), voir cette réponse.
Si vous êtes derrière un pare-feu NAT comme le wifi de votre box à la maison, alors ce ne sera pas montrer à votre public NAT IP, mais au lieu de votre privée NAT IP sur le réseau local, ce qui a une route par défaut local de votre routeur wi-fi; l'obtention de votre routeur wifi IP externe serait soit d'exiger l'exécution de cette dans CETTE zone, ou de le connecter à un service externe comme whatismyip.com/whatismyipaddress.com cela pourrait refléter l'arrière de la propriété intellectuelle... mais qui est complètement différent de la question d'origine. 🙂
Mis à jour connect() appel par Pedro de la suggestion dans les commentaires. (Si vous avez besoin d'une licence spécifique, ce est dans le domaine public/gratuit pour toute utilisation, ou MIT/CC2-BY-SA par Débordement de Pile du code/contenu de la licence de votre choix.)
Brillant. Fonctionne sur Win7,8,8.1 + Linux Mint & Arch, y compris les machines virtuelles.
Fonctionne dans Windows 10 Pro! Merci, Jamieson Becker!
Pour une raison quelconque, cela ne fonctionne pas sur Mac OS X El Capitan 10.11.6 (il génère une exception OS d'erreur: [Errno 49] ne Peut pas affecter une adresse demandée). Le changement de port à partir de '0' à '1' : s.connect(('10.255.255.255', 1)) a fonctionné pour moi à la fois sur Mac OS X et Linux Ubuntu 17.04
Ce doit être la accepté de répondre.
socket.gethostbyname(socket.gethostname())
donne des résultats horribles.OriginalL'auteur Jamieson Becker
Comme un alias appelé
myip
, qui devrait fonctionner partout:Même que ci-dessus, mais seulement le code Python:
Version qui fonctionne également sur les réseaux locaux sans connexion internet:
(merci @ccpizza)
Fond:
À l'aide de
socket.gethostbyname(socket.gethostname())
n'a pas de travail ici, parce que l'un des ordinateurs que j'était sur eu un/etc/hosts
avec les doublons et les références à lui-même.socket.gethostbyname()
retourne seulement la dernière entrée dans/etc/hosts
.C'était ma première tentative, ce qui élimine toutes les adresses commençant par
"127."
:Cela fonctionne avec Python 2 et 3, sur Linux et Windows, mais ne permet pas de traiter avec plusieurs périphériques réseau ou IPv6. Cependant, il a cessé de travailler sur les dernières distributions Linux, j'ai donc essayé cette technique alternative à la place. Il essaie de se connecter à Google serveur DNS à
8.8.8.8
au port53
:Alors j'ai combiné les deux techniques ci-dessus dans un one-liner qui devrait fonctionner partout, et a créé la
myip
alias et extrait Python en haut de cette réponse.Avec la popularité croissante de l'IPv6, et pour les serveurs avec plusieurs interfaces réseau, à l'aide d'un tiers d'un module Python pour trouver l'adresse IP est probablement à la fois plus robuste et plus fiable que les méthodes décrites ici.
Juste pour dire que cette réponse est beaucoup moins utile qu'elle ne l'habitude d'être (et ce n'est pas comme le filtrage des doublons est une grosse affaire ;). Selon la documentation
socket.getaddrinfo()
devrait fonctionner de manière cohérente à travers les plates-formes - mais je ne l'ai vérifié sur Linux, ne vous préoccupez pas de tous les autres systèmes d'exploitation.Je peux confirmer que la version mise à jour fonctionne avec Ubuntu 14.04 avec les deux Python2 et Py3k.
La "mise à jour" montre un joli truc avec connect() sur une socket UDP. Il n'envoie pas de trafic, mais ne vous permettent de trouver ce que serait l'adresse de l'expéditeur pour les paquets vers le destinataire spécifié. Le port est probablement pas pertinent (même à 0 devrait fonctionner). Sur un hôte multirésident il est important de choisir une adresse dans le droit de sous-réseau.
juste parce que vous pouvez écrire ce code sur une seule ligne, cela ne signifie pas que vous devriez...
OriginalL'auteur Alexander
Vous pouvez utiliser le netifaces module. Il suffit de taper:
dans votre invite de commande et il va s'installer sur le défaut d'installation de Python.
Alors vous pouvez l'utiliser comme ceci:
Sur mon ordinateur, de l'imprimer:
Auteur de ce module de réclamations il devrait fonctionner sur Windows, UNIX et Mac OS X.
Ce serait mon préféré réponse, sauf que netifaces ne prend pas en charge IPv6 sur Windows et semble plus maintenu. Quelqu'un a compris comment faire les adresses IPv6 sur Windows?
netifaces ne prend pas en charge py3k, et nécessite un compilateur C qui est un pain PITA sur windows.
Aucune de ces choses n'est plus vrai (la dernière version a des binaires pour Windows sur PyPI et prend en charge Py3K).
FWIW, la dernière version de netifaces t support IPv6 sur Windows.
OriginalL'auteur DzinX
API Socket méthode
voir https://stackoverflow.com/a/28950776/711085
Inconvénients:
Réflecteur méthode
(Notez que cela ne répond pas à l'OP de la question de l'adresse IP locale, par exemple 192.168...; il vous donne votre adresse IP publique, qui pourrait être plus souhaitable, selon les cas d'utilisation.)
Vous pouvez interroger certains sites comme whatismyip.com (mais avec une API), tels que:
ou si vous utilisez python2:
Avantages:
Inconvénients (et les solutions):
modifier: Si au départ j'ai pensé que ces méthodes ont été vraiment mauvais (sauf si vous utilisez plusieurs issues, le code peut être pas pertinent de nombreuses années à partir de maintenant), il pose la question "qu'est-ce que l'internet?". Un ordinateur peut avoir de nombreux liens pointant vers beaucoup de différents réseaux. Pour une description plus détaillée du sujet, google pour
gateways and routes
. Un ordinateur peut être en mesure d'accéder à un réseau interne via une gateway interne, ou d'accéder à la world-wide web par le biais d'une passerelle, par exemple un routeur (généralement le cas). L'adresse IP locale que l'OP pose des questions sur n'est bien définie par rapport à une seule couche de liaison, de sorte que vous avez à préciser que ("est-ce la carte réseau ou le câble ethernet, ce qui nous parlons?"). Il peut y avoir plusieurs non-uniques réponses à cette question posée. Cependant, l'adresse IP globale sur le world wide web est probablement bien définies (en l'absence de l'immense réseau de la fragmentation): probablement la voie de retour via la passerelle qui peut accéder au Tld.vous devez par psychiques, parce que je viens de modifier ma réponse à la dire que!
Il ne veut pas créer une connexion TCP, car elle crée une connexion UDP.
ah oups, bien sûr, je vous remercie...
Comme une alternative dans la prise, la version de l'API, de remplacer les.connect (("INSÉRER une CIBLE WEBSITE.com', 0)) avec s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1);s.connect(('<émission>', 0)) pour éviter de recherche DNS. (Je pense qu'il y a peut-être un problème avec une diffusion si il y a un pare-feu)
OriginalL'auteur ninjagecko
Si l'ordinateur dispose d'un itinéraire à l'Internet, ce sera toujours de travail pour obtenir le préféré adresse ip locale, même si /etc/hosts n'est pas réglé correctement.
s.connect(('8.8.8.8', 0))
échoue sur Mac (error: [Errno 49] Can't assign requested address
) maiss.connect(('8.8.8.8', 1))
fonctionne bien.vous vous êtes liés d'informations sur les DNS que nous ne faisons pas ici. Nous ne sommes pas demander toute information provenant du monde extérieur. L'UDP "se connecter" seulement prépare un socket pour commencer l'envoi de paquets. Si nous avions à faire.s.send(), alors, oui, nous serions en l'envoi de paquets. Je ne suis pas sûr de ce que cela a à voir avec votre lien.
Les deux erm3nda les commentaires sont dans l'erreur. Connectez échoue pas "parce que vous ne pouvez pas ping google" (ce code n'est pas une requête ping à quoi que ce soit), ping normale n'est pas "répondre sur le port 1" (ping ICMP, les ports UDP/TCP). Et pas de paquets sont envoyés sur UDP connecter, au moins jusqu'à présent, comme indiqué par les sources fournis. @erm3nda, veuillez les supprimer ou les modifier afin de ne pas embrouiller les gens
le port 0 est un port réservé ailleurs, alors tecnically personne ne va l'utiliser pour communiquer. Ce n'est pas un Mac chose.
OriginalL'auteur Collin Anderson
Sur Linux:
Le socket est ouvert pour obtenir un fd pour communiquer avec le noyau (via
ioctl
). Le socket n'est pas lié à l'interface pour laquelle vous voulez l'adresse d'infos sur - son juste un mécanisme de communication entre l'espace utilisateur et le noyau. en.wikipedia.org/wiki/Ioctl lxr.free-electrons.com/source/net/socket.cFonctionne sur Python3 avec une modification:
struct.pack('16sH14s', iface, socket.AF_INET, '\x00'*14)
doit être remplacé parstruct.pack('16sH14s', iface.encode('utf-8'), socket.AF_INET, b'\x00'*14)
est un héritage de l'interface je ne crois pas en charge IPv6 et probablement ne le sera jamais. Je pense que le "Droit" est via Netlink ce qui n'est pas très simple en Python. Je pense que la libc doit avoir la fonction
getifaddrs
qui peuvent être accessibles via des pythonsctypes
module qui fonctionne - man7.org/linux/man-pages/man3/getifaddrs.3.htmlioctl est un héritage de l'interface je ne crois pas en charge IPv6 et probablement ne le sera jamais. Je pense que le "Droit" est via Netlink ce qui n'est pas très simple en Python. Je pense que la libc doit avoir la fonction getifaddrs qui peuvent être accessibles via des pythons ctypes module qui fonctionne - man7.org/linux/man-pages/man3/getifaddrs.3.html
OriginalL'auteur tMC
im en utilisant module suivant:
Testé avec windows et linux (et ne marche pas besoin de modules supplémentaires pour celles-ci)
conçu pour une utilisation sur des systèmes qui sont en une seule IPv4 réseau local en fonction.
Fixe la liste des noms d'interface ne fonctionne pas pour les dernières versions de linux, qui ont adopté l'systemd v197 changement prévisible concernant les noms d'interface comme l'a souligné Alexander.
Dans de tels cas, vous devez remplacer manuellement la liste avec les noms d'interface sur votre système, ou d'utiliser une autre solution comme netifaces.
enp0s25
. Pour plus d'informations, voir wiki.archlinux.org/index.php/Network_Configuration#Device_namesJ'ai été à l'aide de python 3.4 et le 'struct.pack de(...)' partie qui doit être changé pour " struct.pack('256s', octets(ifname[:15], 'utf-8'))'. Voir cette question: stackoverflow.com/q/27391167/76010
sur Raspbian w/ Python 2.7.3 - octets() n'a pas comme le 2ème argument. Mais cela a fonctionné:
struct.pack('256s', bytes(ifname[:15]))
OriginalL'auteur smerlin
Je l'utiliser sur mon ubuntu machines:
Cela ne fonctionne pas.
Donc, vous devriez utiliser "/sbin/ifconfig" comme gavaletz dit. Il travaille aussi sur Red Hat 4.1.2-48.
Obsolète depuis la 2.6. Utiliser le sous-processus module pour exécuter des commandes.
Et ifconfig est obsolète. Utilisation iproute2.
Obtenez toutes les ips: importation de poisson; [ip.split()[1][5:] de la propriété intellectuelle dans filter(lambda x: 'inet addr" en x, sh.ifconfig().split("\n"))]
OriginalL'auteur shino
Si vous ne voulez pas utiliser les paquets externes et ne veux pas compter sur l'extérieur des serveurs d'Internet, cela peut aider. C'est un exemple de code que j'ai trouvé sur Google Recherche De Code et modifié pour renvoyer les informations nécessaires:
Utilisation:
Puisqu'il repose sur
windll
, cela ne fonctionne que sur Windows.+1 Cette technique au moins tente de retourner toutes les adresses de la machine.
Ce script échoue sur ma machine après le retour à la première adresse. L'erreur est "AttributeError: 'LP_IP_ADDR_STRING' objet n'a pas d'attribut "ipAddress " de" je soupçonne qu'il a quelque chose à voir avec l'adresse IPv6.
Il s'avère que le problème est que pour quelque chose, mais la première adresse IP, le adNode n'est pas déréférencé. Ajouter une ligne supplémentaire à l'exemple de la boucle while et ça fonctionne pour moi: adNode = adNode.contenu
OriginalL'auteur DzinX
Une version que je ne crois pas qu'a été publié pour le moment.
J'ai testé avec python 2.7 sur Ubuntu 12.04.
Trouvé cette solution : http://code.activestate.com/recipes/439094-get-the-ip-address-associated-with-a-network-inter/
Exemple De Résultat:
Fonctionne sur Python3, Ubuntu 18.04; La chaîne doit être octets: >>> socket.inet_ntoa(fcntl.ioctl(s).fileno(), 0x8915, struct.pack('256s', 'enp0s31f6'[:15].encode('utf-8')))[20:24]) '192.168.1.1'
OriginalL'auteur Graham Chap
Sur Debian (testé) et je soupçonne la plupart des Linux..
Sur MS Windows (testé)
Ne fonctionne pas sous macOS:
hostname: illegal option -- I\nusage: hostname [-fs] [name-of-host]
OriginalL'auteur www-0av-Com
Variation sur ninjagecko de réponse. Cela devrait fonctionner sur n'importe quel réseau local qui permet la diffusion UDP et ne nécessite pas l'accès à une adresse sur le réseau local ou internet.
<broadcast>
un nom d'hôte valide?!! Comment beaucoup de ces types de verbal les noms d'hôtes sont-ils valables?OriginalL'auteur dlm
J'ai peur, il n'y a pas une bonne plate-forme indépendante de façons de le faire d'autre que de la connexion à un autre ordinateur et de vous envoyer votre adresse IP. Par exemple: findmyipaddress. Notez que cela ne fonctionne pas si vous avez besoin d'une adresse IP qui est derrière un NAT, sauf si l'ordinateur auquel vous vous connectez est derrière un NAT.
Voici une solution qui fonctionne sous Linux: obtenir l'adresse IP associée à une interface réseau.
OriginalL'auteur Jason Baker
Un moyen simple de produire "propre" de sortie via la ligne de commande utils:
Il indiquera toutes les adresses IPv4 sur le système.
C'est un enfer de beaucoup de shell pour une question demandant la bibliothèque standard... Aussi, l'analyse de la commande ifconfig est ni portable et ne seront même pas fonctionner sur une seule machine.
OriginalL'auteur viker
Pour info je peux vérifier que la méthode:
Fonctionne sous OS X (10.6,10.5), Windows XP, et bien administré RHEL serveur de service. Il ne fonctionne pas sur une très minime VM CentOS que je viens de faire quelques noyau sur le piratage. Donc, pour cette instance, vous pouvez simplement vérifier une adresse 127.0.0.1 et dans ce cas, procédez de la manière suivante:
Et ensuite d'analyser l'adresse ip à partir de la sortie. Il convient de noter que ifconfig n'est pas dans un état normal de l'utilisateur du CHEMIN d'accès par défaut et c'est pourquoi je donne le chemin complet de la commande. J'espère que cette aide.
OriginalL'auteur gavaletz
C'est une variante de UnkwnTech de la réponse -- il fournit un
get_local_addr()
la fonction, qui renvoie à la primaire de l'adresse ip LAN de l'ordinateur hôte. Je poste parce que cela ajoute un certain nombre de choses: prise en charge d'ipv6, erreur de manipulation, ignorant localhost/linklocal addrs, et utilise un TESTNET addr (rfc5737) pour vous connecter à.OriginalL'auteur Eli Collins
Cela fonctionne sur la plupart des boîtes de linux:
OriginalL'auteur fccoelho
Donne-moi
['fe80::34e8:fe19:1459:2cde%22','fe80::d528:99fb:d572:e289%12', '192.168.56.1', '192.168.1.2']
sur le bureau de Windows.OriginalL'auteur Nakilon
Cette réponse, c'est ma façon personnelle de tenter de résoudre le problème de l'obtention de l'adresse IP LAN, depuis
socket.gethostbyname(socket.gethostname())
également retourné 127.0.0.1. Cette méthode ne nécessite pas Internet, il suffit d'une connexion LAN. Le Code est en Python 3.x, mais pourrait facilement être converti pour 2.x. À l'aide de Diffusion UDP:OriginalL'auteur WolfRage
127.0.1.1
est votre véritable adresse IP. De manière plus générale, un ordinateur peut avoir n'importe quel nombre d'adresses IP. Vous pouvez les filtrer pour les réseaux privés - 127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12 et 192.168.0.0/16.Cependant, il n'y a pas de croix-plate-forme de façon à obtenir toutes les adresses IP. Sur Linux, vous pouvez utiliser le
SIOCGIFCONF
ioctl.OriginalL'auteur phihag
Une légère raffinement des commandes de la version qui utilise l'IP de commande, et renvoie les adresses IPv4 et IPv6:
OriginalL'auteur Ben Last
Eh bien, vous pouvez utiliser la commande "ip route" sur GNU/Linux pour connaître votre adresse IP actuelle.
Cela montre l'IP donnée à l'interface par le serveur DHCP fonctionne sur le routeur/modem. Généralement "192.168.1.1/24" est l'adresse IP pour le réseau local où "24" s'entend de la gamme des possibles adresses IP donnée par le serveur DHCP dans le masque de la gamme.
Voici un exemple: Notez que PyNotify est juste un plus d'obtenir mon point de droit et n'est pas nécessaire à tous les
L'avantage, c'est que vous n'avez pas besoin de spécifier l'interface réseau. C'est très utile lors de l'exécution d'un serveur socket
Vous pouvez installer PyNotify utiliser easy_install ou même Pip:
ou
ou à l'intérieur d'un script python/interprète
OriginalL'auteur DarkXDroid
Remarque: Ce n'est pas à l'aide de la bibliothèque standard, mais assez simple.
$ pip install pif
OriginalL'auteur Artur Barseghyan
netifaces est disponible via pip et easy_install. (Je sais, ce n'est pas dans la base, mais il pourrait être la peine de l'installer.)
netifaces a quelques bizarreries sur les plates-formes:
Voici quelques netifaces code pour jouer avec:
Le code ci-dessus ne correspondent pas à une adresse de retour à son nom de l'interface (utile pour générer des ebtables/règles iptables à la volée). Voici donc une version qui conserve les informations ci-dessus avec le nom de l'interface dans un tuple:
Et, non, je ne suis pas en amour avec les interprétations de la liste. C'est juste la façon dont mon cerveau fonctionne de nos jours.
L'extrait de code suivant apparaîtra à l'impression de tout:
Profitez-en!
OriginalL'auteur user3712955
Pour obtenir l'adresse ip, vous pouvez utiliser un commande shell directement dans python:
OriginalL'auteur RiccardoCh
Cela vous renvoie l'adresse IP dans le système Ubuntu ainsi que MacOS. La sortie est l'adresse IP du système comme my IP: 192.168.1.10.
OriginalL'auteur Ishwarya
Si vous êtes à la recherche d'une adresse IPV4 est différente de votre adresse IP localhost
127.0.0.1
, ici, est d'un joli morceau de python codes:Qui peut aussi être écrit en une seule ligne:
Même si vous mettez
localhost
dans/etc/hostname
, le code sera toujours donner votre adresse IP locale.OriginalL'auteur hmofrad
J'ai eu à résoudre le problème de "déterminer si une adresse IP est local ou non", et ma première pensée a été de construire une liste d'adresses ip qui ont été locale, puis match contre elle. C'est ce qui m'a amené à cette question. Cependant, j'ai réalisé plus tard il est plus simple façon de le faire: Essayer de lier sur la propriété intellectuelle et de voir si cela fonctionne.
Je sais que ce n'est pas répondre directement à la question, mais cela devrait être utile pour quiconque d'essayer de résoudre la question connexe et qui avait suivi la même ligne de pensée. Cela a l'avantage d'être une solution multi-plateforme (je pense).
OriginalL'auteur Etienne Perot