Trouver des adresses IP locales en utilisant Stdlib de Python
Comment puis-je trouver des adresses IP locales (i.e. 192.168.x.x ou 10.0.x.x) dans la plate-forme Python indépendamment et en utilisant seulement la bibliothèque standard?
30 réponses
import socket
socket.gethostbyname(socket.gethostname())
cela ne fonctionnera pas toujours (renvoie 127.0.0.1
sur les machines ayant le nom d'hôte dans /etc/hosts
comme 127.0.0.1
), un paliatif serait ce que gimel montre, utilisez socket.getfqdn()
à la place. Bien sûr, votre machine a besoin d'un nom d'hôte résoluble.
je viens de trouver ceci mais il semble un peu hackish, cependant ils disent l'a essayé sur *nix et je l'ai fait sur windows et il a fonctionné.
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
print(s.getsockname()[0])
s.close()
cela suppose que vous avez un accès internet, et qu'il n'y a pas de mandataire local.
comme un alias appelé myip
, qui devrait fonctionner partout:
alias myip="python -c 'import socket; print([l for l in ([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith(\"127.\")][:1], [[(s.connect((\"8.8.8.8\", 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1]]) if l][0][0])'"
- fonctionne correctement avec Python 2.x, Python 3.x, Linux moderne et ancien distros, OSX / macOS et Windows pour trouver l'adresse IPv4 actuelle.
- ne retournera pas le résultat correct pour les machines avec plusieurs adresses IP, IPv6, pas d'adresse IP configurée ou pas d'accès internet.
comme ci-dessus, mais seulement le code Python:
import socket
print([l for l in ([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith("127.")][:1], [[(s.connect(('8.8.8.8', 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1]]) if l][0][0])
- il s'agit d'une exception si aucune adresse IP n'est configurée.
Version qui fonctionnera également sur les réseaux locaux sans connexion internet:
import socket
print((([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith("127.")] or [[(s.connect(("8.8.8.8", 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1]]) + ["no IP found"])[0])
(merci @ccpizza )
arrière-plan :
en utilisant socket.gethostbyname(socket.gethostname())
n'a pas fonctionné ici, parce que l'un des ordinateurs sur lequel j'étais avait un /etc/hosts
avec des entrées en double et des références à lui-même. socket.gethostbyname()
renvoie seulement la dernière entrée dans /etc/hosts
.
c'était ma première tentative, qui élimine toutes les adresses commençant par "127."
:
import socket
print([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith("127.")][:1])
cela fonctionne avec Python 2 et 3, sur Linux et Windows, mais ne traite pas de plusieurs périphériques réseau ou IPv6. Cependant, il a cessé de travailler sur des distributions Linux récentes, donc j'ai essayé cette technique alternative à la place. Il essaie de se connecter au serveur Google DNS à 8.8.8.8
au port 53
:
import socket
print([(s.connect(('8.8.8.8', 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1])
puis j'ai combiné les deux techniques ci-dessus dans une doublure unique qui devrait fonctionner partout, et j'ai créé l'alias myip
et l'extrait de Python en haut de cette réponse.
avec la popularité croissante D'IPv6, et pour les serveurs avec plusieurs interfaces réseau, l'utilisation d'un module Python tiers pour trouver l'adresse IP est probablement plus robuste et fiable que n'importe laquelle des méthodes énumérées ici.
cette méthode renvoie l'IP "primaire" sur la boîte locale (celle avec une route par défaut) .
- N'a pas besoin d'accès au réseau routable ou de connexion du tout.
- fonctionne même si toutes les interfaces sont débranchées du réseau.
- N'a pas besoin ou même essayer d'obtenir n'importe où ailleurs .
- Fonctionne avec la NAT, public, privé, externes et internes IP's
- pur Python 2 (ou 3) sans dépendances externes.
- fonctionne sous Linux, Windows et OSX.
Python 2 ou 3:
import socket
def get_ip():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
# doesn't even have to be reachable
s.connect(('10.255.255.255', 1))
IP = s.getsockname()[0]
except:
IP = '127.0.0.1'
finally:
s.close()
return IP
renvoie une seule IP qui est primaire (celle avec une route par défaut). Si vous avez besoin à la place de toutes les IP attachées à toutes les interfaces (y compris localhost, etc), voir cette réponse .
si vous êtes derrière un NAT pare-feu comme votre boîte Wi-Fi à la maison, alors cela ne montrera pas votre IP NAT publique, mais plutôt votre IP NAT privée sur le réseau local qui a une route par défaut à votre routeur WIFI local; obtenir L'IP externe de votre routeur Wi-Fi nécessiterait soit de l'exécuter sur cette boîte, ou de se connecter à un service externe tel que: whatismyip.com/whatismyipaddress.com cela pourrait refléter la période D'enquête... mais c'est complètement différent de la question initiale. :)
mise à jour de connect() appelez la suggestion de per Pedro dans les commentaires. (Si vous avez besoin d'une déclaration de licence spécifique, C'est du domaine public/gratuit pour toute utilisation, ou MIT/CC2-BY-SA par Licence Code/content de Stack Overflow à votre choix.)
vous pouvez utiliser le module netifaces . Tapez juste:
pip install netifaces
dans votre shell de commande et il s'installera lui-même sur l'installation par défaut de Python.
, Alors vous pouvez l'utiliser comme ceci:
from netifaces import interfaces, ifaddresses, AF_INET
for ifaceName in interfaces():
addresses = [i['addr'] for i in ifaddresses(ifaceName).setdefault(AF_INET, [{'addr':'No IP addr'}] )]
print '%s: %s' % (ifaceName, ', '.join(addresses))
sur mon ordinateur il a imprimé:
{45639BDC-1050-46E0-9BE9-075C30DE1FBC}: 192.168.0.100 {D43A468B-F3AE-4BF9-9391-4863A4500583}: 10.5.9.207
L'auteur de ce module affirme qu'il devrait fonctionner sur Windows, UNIX et Mac OS X.
API Socket méthode
voir https://stackoverflow.com/a/28950776/711085
inconvénients:
- Pas de croix-plateforme.
- nécessite plus de code de repli, lié à l'existence d'adresses particulières sur l'internet
- Cela ne fonctionnera pas si vous êtes derrière un NAT
- crée probablement une connexion UDP, qui n'est pas indépendante de la disponibilité du DNS (voir d'autres réponses pour des idées comme l'utilisation de 8.8.8.8: serveur Google (par coïncidence aussi DNS))
- assurez-vous de rendre L'adresse de destination inaccessible, comme une adresse IP numérique qui est spec-garantie d'être inutilisée. N'utilisez pas un domaine comme fakesubdomain.google.com ou somefakewebsite.com; vous serez toujours spamming cette partie (maintenant ou dans le futur), et spamming votre propre réseau de cases bien dans le processus.
méthode du réflecteur
(notez que cela ne répond pas à la question de L'adresse IP locale de L'OP, par exemple 192.168...; il vous donne votre adresse IP publique, qui pourrait être plus souhaitable, selon les cas d'utilisation.)
vous pouvez interroger un site comme whatismyip.com (mais avec une API), comme:
from urllib.request import urlopen
import re
def getPublicIp():
data = str(urlopen('http://checkip.dyndns.com/').read())
# data = '<html><head><title>Current IP Check</title></head><body>Current IP Address: 65.96.168.198</body></html>\r\n'
return re.compile(r'Address: (\d+\.\d+\.\d+\.\d+)').search(data).group(1)
ou si vous utilisez python2:
from urllib import urlopen
import re
def getPublicIp():
data = str(urlopen('http://checkip.dyndns.com/').read())
# data = '<html><head><title>Current IP Check</title></head><body>Current IP Address: 65.96.168.198</body></html>\r\n'
return re.compile(r'Address: (\d+\.\d+\.\d+\.\d+)').search(data).group(1)
avantages:
- L'un des avantages de cette méthode est son cross-platform
- il fonctionne de derrière NATS laid (par exemple votre routeur à la maison).
inconvénients (et solutions de rechange):
- exige que ce site Web soit up, que le format ne change pas (presque certainement pas), et que vos serveurs DNS fonctionnent. On peut atténuer ce problème en interrogeant également d'autres réflecteurs D'adresse IP tiers en cas de défaillance.
- vecteur d'attaque Possible si vous n'interrogez pas plusieurs réflecteurs (pour empêcher un réflecteur compromis de vous dire que votre adresse est quelque chose qu'il n'est pas), ou si vous n'utilisez pas HTTPS (pour empêcher un homme-dans-le-milieu attaque prétendre être le serveur)
modifier : bien que au départ, j'ai pensé que ces méthodes étaient vraiment mauvaises (à moins que vous n'utilisiez de nombreuses solutions de rechange, le code pourrait être hors de propos dans de nombreuses années), 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 passerelle interne, ou accéder au World-wide web via une passerelle sur par exemple un routeur (généralement le cas). Le l'adresse IP locale que L'OP demande n'est bien définie que par rapport à une couche de lien unique, donc vous devez spécifier que ("Est-ce la carte réseau, ou le câble ethernet, dont nous parlons?"). Il peut y avoir plusieurs réponses non uniques à cette question telle qu'elle est posée. Toutefois, l'adresse IP globale sur le World-wide web est probablement bien définie (en l'absence de fragmentation massive du réseau): probablement le chemin de retour via la passerelle qui peut accéder aux TLD.
si l'ordinateur a une route vers L'Internet, cela fonctionnera toujours pour obtenir l'adresse ip locale préférée, même si /etc/hosts n'est pas configuré correctement.
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(('8.8.8.8', 1)) # connect() for UDP doesn't send packets
local_ip_address = s.getsockname()[0]
Sur Linux:
>>> import socket, struct, fcntl
>>> sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> sockfd = sock.fileno()
>>> SIOCGIFADDR = 0x8915
>>>
>>> def get_ip(iface = 'eth0'):
... ifreq = struct.pack('16sH14s', iface, socket.AF_INET, '\x00'*14)
... try:
... res = fcntl.ioctl(sockfd, SIOCGIFADDR, ifreq)
... except:
... return None
... ip = struct.unpack('16sH2x4s8x', res)[2]
... return socket.inet_ntoa(ip)
...
>>> get_ip('eth0')
'10.80.40.234'
>>>
im utilisant le module suivant:
#!/usr/bin/python
# module for getting the lan ip address of the computer
import os
import socket
if os.name != "nt":
import fcntl
import struct
def get_interface_ip(ifname):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
return socket.inet_ntoa(fcntl.ioctl(
s.fileno(),
0x8915, # SIOCGIFADDR
struct.pack('256s', bytes(ifname[:15], 'utf-8'))
# Python 2.7: remove the second argument for the bytes call
)[20:24])
def get_lan_ip():
ip = socket.gethostbyname(socket.gethostname())
if ip.startswith("127.") and os.name != "nt":
interfaces = ["eth0","eth1","eth2","wlan0","wlan1","wifi0","ath0","ath1","ppp0"]
for ifname in interfaces:
try:
ip = get_interface_ip(ifname)
break;
except IOError:
pass
return ip
Testé avec windows et linux (et ne nécessite pas de modules supplémentaires pour ceux) destiné à être utilisé sur des systèmes qui sont dans un seul réseau local IPv4.
la liste fixe des noms d'interface ne fonctionne pas pour les versions récentes de linux, qui ont adopté le changement systemd v197 concernant les noms d'interface prévisibles comme souligné par Alexander . Dans de tels cas, vous devez remplacez manuellement la liste par les noms d'interface sur votre système, ou utilisez une autre solution comme netifaces .
j'utilise ce sur mes machines ubuntu:
import commands
commands.getoutput("/sbin/ifconfig").split("\n")[1].split()[1][5:]
ça ne marche pas.
si vous ne voulez pas utiliser de paquets externes et ne voulez pas compter sur des serveurs Internet externes, cela pourrait vous aider. C'est un échantillon de code que j'ai trouvé sur recherche de code Google et modifié pour retourner les informations requises:
def getIPAddresses():
from ctypes import Structure, windll, sizeof
from ctypes import POINTER, byref
from ctypes import c_ulong, c_uint, c_ubyte, c_char
MAX_ADAPTER_DESCRIPTION_LENGTH = 128
MAX_ADAPTER_NAME_LENGTH = 256
MAX_ADAPTER_ADDRESS_LENGTH = 8
class IP_ADDR_STRING(Structure):
pass
LP_IP_ADDR_STRING = POINTER(IP_ADDR_STRING)
IP_ADDR_STRING._fields_ = [
("next", LP_IP_ADDR_STRING),
("ipAddress", c_char * 16),
("ipMask", c_char * 16),
("context", c_ulong)]
class IP_ADAPTER_INFO (Structure):
pass
LP_IP_ADAPTER_INFO = POINTER(IP_ADAPTER_INFO)
IP_ADAPTER_INFO._fields_ = [
("next", LP_IP_ADAPTER_INFO),
("comboIndex", c_ulong),
("adapterName", c_char * (MAX_ADAPTER_NAME_LENGTH + 4)),
("description", c_char * (MAX_ADAPTER_DESCRIPTION_LENGTH + 4)),
("addressLength", c_uint),
("address", c_ubyte * MAX_ADAPTER_ADDRESS_LENGTH),
("index", c_ulong),
("type", c_uint),
("dhcpEnabled", c_uint),
("currentIpAddress", LP_IP_ADDR_STRING),
("ipAddressList", IP_ADDR_STRING),
("gatewayList", IP_ADDR_STRING),
("dhcpServer", IP_ADDR_STRING),
("haveWins", c_uint),
("primaryWinsServer", IP_ADDR_STRING),
("secondaryWinsServer", IP_ADDR_STRING),
("leaseObtained", c_ulong),
("leaseExpires", c_ulong)]
GetAdaptersInfo = windll.iphlpapi.GetAdaptersInfo
GetAdaptersInfo.restype = c_ulong
GetAdaptersInfo.argtypes = [LP_IP_ADAPTER_INFO, POINTER(c_ulong)]
adapterList = (IP_ADAPTER_INFO * 10)()
buflen = c_ulong(sizeof(adapterList))
rc = GetAdaptersInfo(byref(adapterList[0]), byref(buflen))
if rc == 0:
for a in adapterList:
adNode = a.ipAddressList
while True:
ipAddr = adNode.ipAddress
if ipAddr:
yield ipAddr
adNode = adNode.next
if not adNode:
break
Utilisation:
>>> for addr in getIPAddresses():
>>> print addr
192.168.0.100
10.5.9.207
comme il s'appuie sur windll
, cela ne fonctionnera que sur Windows.
sur Debian (testé) et je soupçonne la plupart des Linux..
import commands
RetMyIP = commands.getoutput("hostname -I")
sur MS Windows (testé)
import socket
socket.gethostbyname(socket.gethostname())
une version que je ne crois pas encore avoir été postée. J'ai testé avec python 2.7 sur Ubuntu 12.04.
a trouvé cette solution à: http://code.activestate.com/recipes/439094-get-the-ip-address-associated-with-a-network-inter /
import socket
import fcntl
import struct
def get_ip_address(ifname):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
return socket.inet_ntoa(fcntl.ioctl(
s.fileno(),
0x8915, # SIOCGIFADDR
struct.pack('256s', ifname[:15])
)[20:24])
Exemple De Résultat:
>>> get_ip_address('eth0')
'38.113.228.130'
j'ai bien peur qu'il n'y ait aucun bon moyen indépendant de la plate-forme pour faire cela autre que de se connecter à un autre ordinateur et de le faire vous envoyer votre adresse IP. Par exemple: findmyipaddress . Notez que cela ne fonctionnera pas si vous avez besoin d'une adresse IP qui est derrière le NAT à moins que l'ordinateur auquel vous vous connectez soit aussi derrière le NAT.
Voici une solution qui fonctionne sous Linux: obtenir l'adresse IP associée à une interface réseau .
une façon simple de produire une sortie "propre" via les outils de ligne de commande:
import commands
ips = commands.getoutput("/sbin/ifconfig | grep -i \"inet\" | grep -iv \"inet6\" | " +
"awk {'print '} | sed -ne 's/addr\:/ /p'")
print ips
il affichera toutes les adresses IPv4 sur le système.
FYI je peux vérifier que la méthode:
import socket
addr = socket.gethostbyname(socket.gethostname())
fonctionne sous OS X (10.6,10.5), Windows XP, et sur un serveur RHEL department bien administré. Cela n'a pas fonctionné sur une VM CentOS très minimale sur laquelle je viens de faire un piratage du noyau. Donc, pour cette instance, vous pouvez simplement vérifier une adresse 127.0.0.1 et dans ce cas faire ce qui suit:
if addr == "127.0.0.1":
import commands
output = commands.getoutput("/sbin/ifconfig")
addr = parseaddress(output)
et puis analyser l'adresse ip à partir de la sortie. Il convient de noter que ifconfig n'est pas dans un chemin normal de l'utilisateur par défaut et c'est pourquoi je donne le chemin complet dans la commande. J'espère que cette aide.
c'est une variante de la réponse D'UnkwnTech -- il fournit une fonction get_local_addr()
, qui renvoie l'adresse IP du réseau local principal de l'hôte. Je l'affiche parce que cela ajoute un certain nombre de choses: le support ipv6, la gestion des erreurs, l'ignorance des addrs localhost/linklocal, et utilise un addr TESTNET (rfc5737) pour se connecter.
# imports
import errno
import socket
# localhost prefixes
_local_networks = ("127.", "0:0:0:0:0:0:0:1")
# ignore these prefixes -- localhost, unspecified, and link-local
_ignored_networks = _local_networks + ("0.", "0:0:0:0:0:0:0:0", "169.254.", "fe80:")
def detect_family(addr):
if "." in addr:
assert ":" not in addr
return socket.AF_INET
elif ":" in addr:
return socket.AF_INET6
else:
raise ValueError("invalid ipv4/6 address: %r" % addr)
def expand_addr(addr):
"""convert address into canonical expanded form --
no leading zeroes in groups, and for ipv6: lowercase hex, no collapsed groups.
"""
family = detect_family(addr)
addr = socket.inet_ntop(family, socket.inet_pton(family, addr))
if "::" in addr:
count = 8-addr.count(":")
addr = addr.replace("::", (":0" * count) + ":")
if addr.startswith(":"):
addr = "0" + addr
return addr
def _get_local_addr(family, remote):
try:
s = socket.socket(family, socket.SOCK_DGRAM)
try:
s.connect((remote, 9))
return s.getsockname()[0]
finally:
s.close()
except socket.error:
return None
def get_local_addr(remote=None, ipv6=True):
"""get LAN address of host
:param remote:
return LAN address that host would use to access that specific remote address.
by default, returns address it would use to access the public internet.
:param ipv6:
by default, attempts to find an ipv6 address first.
if set to False, only checks ipv4.
:returns:
primary LAN address for host, or ``None`` if couldn't be determined.
"""
if remote:
family = detect_family(remote)
local = _get_local_addr(family, remote)
if not local:
return None
if family == socket.AF_INET6:
# expand zero groups so the startswith() test works.
local = expand_addr(local)
if local.startswith(_local_networks):
# border case where remote addr belongs to host
return local
else:
# NOTE: the two addresses used here are TESTNET addresses,
# which should never exist in the real world.
if ipv6:
local = _get_local_addr(socket.AF_INET6, "2001:db8::1234")
# expand zero groups so the startswith() test works.
if local:
local = expand_addr(local)
else:
local = None
if not local:
local = _get_local_addr(socket.AF_INET, "192.0.2.123")
if not local:
return None
if local.startswith(_ignored_networks):
return None
return local
cela fonctionnera sur la plupart des boîtes linux:
import socket, subprocess, re
def get_ipv4_address():
"""
Returns IP address(es) of current machine.
:return:
"""
p = subprocess.Popen(["ifconfig"], stdout=subprocess.PIPE)
ifc_resp = p.communicate()
patt = re.compile(r'inet\s*\w*\S*:\s*(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})')
resp = patt.findall(ifc_resp[0])
print resp
get_ipv4_address()
import socket
[i[4][0] for i in socket.getaddrinfo(socket.gethostname(), None)]
Variation sur la réponse de ninjagecko. 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.
import socket
def getNetworkIp():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
s.connect(('<broadcast>', 0))
return s.getsockname()[0]
print (getNetworkIp())
cette réponse est ma tentative personnelle pour résoudre le problème d'obtenir L'IP LAN, puisque socket.gethostbyname(socket.gethostname())
aussi retourné 127.0.0.1. Cette méthode ne nécessite pas Internet juste une connexion LAN. Le Code est pour Python 3.x, mais pourrait facilement être converti pour 2.x. En utilisant la diffusion UDP:
import select
import socket
import threading
from queue import Queue, Empty
def get_local_ip():
def udp_listening_server():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(('<broadcast>', 8888))
s.setblocking(0)
while True:
result = select.select([s],[],[])
msg, address = result[0][0].recvfrom(1024)
msg = str(msg, 'UTF-8')
if msg == 'What is my LAN IP address?':
break
queue.put(address)
queue = Queue()
thread = threading.Thread(target=udp_listening_server)
thread.queue = queue
thread.start()
s2 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s2.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
waiting = True
while waiting:
s2.sendto(bytes('What is my LAN IP address?', 'UTF-8'), ('<broadcast>', 8888))
try:
address = queue.get(False)
except Empty:
pass
else:
waiting = False
return address[0]
if __name__ == '__main__':
print(get_local_ip())
127.0.1.1
est votre adresse IP réelle. Plus généralement, 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 moyen multiplate-forme pour obtenir toutes les adresses IP. Sous Linux, vous pouvez utiliser le SIOCGIFCONF
ioctl.
un léger raffinement de la version des commandes qui utilise la commande IP, et renvoie les adresses IPv4 et IPv6:
import commands,re,socket
#A generator that returns stripped lines of output from "ip address show"
iplines=(line.strip() for line in commands.getoutput("ip address show").split('\n'))
#Turn that into a list of IPv4 and IPv6 address/mask strings
addresses1=reduce(lambda a,v:a+v,(re.findall(r"inet ([\d.]+/\d+)",line)+re.findall(r"inet6 ([\:\da-f]+/\d+)",line) for line in iplines))
#addresses1 now looks like ['127.0.0.1/8', '::1/128', '10.160.114.60/23', 'fe80::1031:3fff:fe00:6dce/64']
#Get a list of IPv4 addresses as (IPstring,subnetsize) tuples
ipv4s=[(ip,int(subnet)) for ip,subnet in (addr.split('/') for addr in addresses1 if '.' in addr)]
#ipv4s now looks like [('127.0.0.1', 8), ('10.160.114.60', 23)]
#Get IPv6 addresses
ipv6s=[(ip,int(subnet)) for ip,subnet in (addr.split('/') for addr in addresses1 if ':' in addr)]
vous pouvez utiliser la commande "ip route" sur GNU/Linux pour connaître votre adresse IP actuelle.
indique L'IP donnée à l'interface par le serveur DHCP tournant sur le routeur/modem. Habituellement " 192.168.1.1 / 24 "est L'IP pour le réseau local où" 24 " signifie la plage d'adresses IP possibles donnée par le serveur DHCP dans la plage de masque.
voici un exemple: notez que PyNotify est juste un ajout pour clarifier mon point et n'est pas nécessaire du tout
#! /usr/bin/env python
import sys , pynotify
if sys.version_info[1] != 7:
raise RuntimeError('Python 2.7 And Above Only')
from subprocess import check_output # Available on Python 2.7+ | N/A
IP = check_output(['ip', 'route'])
Split_Result = IP.split()
# print Split_Result[2] # Remove "#" to enable
pynotify.init("image")
notify = pynotify.Notification("Ip", "Server Running At:" + Split_Result[2] , "/home/User/wireless.png")
notify.show()
L'avantage, c'est que vous n'avez pas besoin de spécifier l'interface réseau. C'est assez utile quand on exécute un serveur socket
vous pouvez installer PyNotify en utilisant easy_install ou même Pip:
easy_install py-notify
ou
pip install py-notify
ou à l'intérieur d'un script python/interprète
from pip import main
main(['install', 'py-notify'])
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:
- l'interface localhost/loop-back n'est pas toujours incluse (Cygwin). Les adresses
- sont listées par protocole (par exemple, IPv4, IPv6) et les protocoles sont listés par interface. Sur certains systèmes (Linux) chaque paire d'interface de protocole a son propre interface associée (en utilisant la notation interface_name:n) tandis que sur D'autres systèmes (Windows) une interface unique aura une liste d'adresses pour chaque protocole. Dans les deux cas, il existe une liste de protocoles, mais elle ne peut contenir qu'un seul élément.
voici quelques codes de netifaces pour jouer avec:
import netifaces
PROTO = netifaces.AF_INET # We want only IPv4, for now at least
# Get list of network interfaces
# Note: Can't filter for 'lo' here because Windows lacks it.
ifaces = netifaces.interfaces()
# Get all addresses (of all kinds) for each interface
if_addrs = [netifaces.ifaddresses(iface) for iface in ifaces]
# Filter for the desired address type
if_inet_addrs = [addr[PROTO] for addr in if_addrs if PROTO in addr]
iface_addrs = [s['addr'] for a in if_inet_addrs for s in a if 'addr' in s]
# Can filter for '127.0.0.1' here.
le code ci-dessus ne renvoie pas une adresse à son nom d'interface (utile pour générer des règles ebtables/iptables à la volée). Si voici une version qui garde les informations ci-dessus avec le nom de l'interface dans un tuple:
import netifaces
PROTO = netifaces.AF_INET # We want only IPv4, for now at least
# Get list of network interfaces
ifaces = netifaces.interfaces()
# Get addresses for each interface
if_addrs = [(netifaces.ifaddresses(iface), iface) for iface in ifaces]
# Filter for only IPv4 addresses
if_inet_addrs = [(tup[0][PROTO], tup[1]) for tup in if_addrs if PROTO in tup[0]]
iface_addrs = [(s['addr'], tup[1]) for tup in if_inet_addrs for s in tup[0] if 'addr' in s]
et, Non, Je ne suis pas amoureux des compréhensions de listes. C'est juste la façon dont mon cerveau fonctionne de nos jours.
l'extrait suivant imprimera tout:
from __future__ import print_function # For 2.x folks
from pprint import pprint as pp
print('\nifaces = ', end='')
pp(ifaces)
print('\nif_addrs = ', end='')
pp(if_addrs)
print('\nif_inet_addrs = ', end='')
pp(if_inet_addrs)
print('\niface_addrs = ', end='')
pp(iface_addrs)
Profitez-en!
pour obtenir l'adresse ip, vous pouvez utiliser une commande shell directement dans python :
import socket, subprocess
def getIpAndHostname():
hostname = socket.gethostname()
shell_cmd = "ifconfig | awk '/inet addr/{print substr(,6)}'"
proc = subprocess.Popen([shell_cmd], stdout=subprocess.PIPE, shell=True)
(out, err) = proc.communicate()
ip_list = out.split('\n')
ip = ip_list[0]
for _ip in ip_list:
try:
if _ip != "127.0.0.1" and _ip.split(".")[3] != "1":
ip = _ip
except:
pass
return ip, hostname
ip_addr, hostname = getIpAndHostname()
j'ai dû résoudre le problème "comprendre si une adresse IP est locale ou non", et ma première pensée a été de construire une liste D'IPs qui étaient locaux et puis match contre elle. C'est ce qui m'a amené à cette question. Cependant, j'ai réalisé plus tard qu'il y avait une façon plus directe de le faire: essayer de lier cette IP et voir si elle fonctionne.
_local_ip_cache = []
_nonlocal_ip_cache = []
def ip_islocal(ip):
if ip in _local_ip_cache:
return True
if ip in _nonlocal_ip_cache:
return False
s = socket.socket()
try:
try:
s.bind((ip, 0))
except socket.error, e:
if e.args[0] == errno.EADDRNOTAVAIL:
_nonlocal_ip_cache.append(ip)
return False
else:
raise
finally:
s.close()
_local_ip_cache.append(ip)
return True
je sais que cela ne répond pas directement à la question, mais cela devrait être utile à quiconque essaie 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 multiplateformes (je pense).
Note: Ce n'est pas utiliser la bibliothèque standard, mais tout à fait simple.
$ pip install pif
from pif import get_public_ip
get_public_ip()
import netifaces as ni
ni.ifaddresses('eth0')
ip = ni.ifaddresses('eth0')[ni.AF_INET][0]['addr']
print(ip)
cela vous retournera l'adresse IP dans le système Ubuntu ainsi que MacOS. La sortie sera l'adresse IP du système comme mon adresse IP: 192.168.1.10.