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?

429
demandé sur anatoly techtonik 2008-10-03 16:03:36

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.

349
répondu Vinko Vrsalovic 2015-07-02 19:22:58

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.

357
répondu UnkwnTech 2017-03-31 19:06:53

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.

132
répondu Alexander 2018-08-08 07:09:45

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.)

103
répondu Jamieson Becker 2018-08-19 22:03:05

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.

80
répondu DzinX 2017-10-22 08:55:05

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.

48
répondu ninjagecko 2018-04-05 17:14:36

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]
40
répondu Collin Anderson 2017-03-29 15:12:35

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'
>>> 
38
répondu tMC 2012-09-07 18:15:45

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 .

26
répondu smerlin 2015-10-27 12:12:16

j'utilise ce sur mes machines ubuntu:

import commands
commands.getoutput("/sbin/ifconfig").split("\n")[1].split()[1][5:]

ça ne marche pas.

25
répondu shino 2018-01-26 09:48:46

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.

19
répondu DzinX 2008-10-03 13:54:11

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())
15
répondu www-0av-Com 2014-07-03 23:43:07

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'
13
répondu Graham Chap 2018-06-08 12:50:38

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 .

8
répondu Jason Baker 2008-10-03 12:19:17

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.

8
répondu viker 2012-07-11 22:03:47

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.

7
répondu gavaletz 2009-12-30 15:51:21

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
7
répondu Eli Collins 2013-12-20 18:41:48

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()
6
répondu fccoelho 2012-04-27 12:14:01
import socket
[i[4][0] for i in socket.getaddrinfo(socket.gethostname(), None)]
6
répondu Nakilon 2013-05-07 06:54:33

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())
6
répondu dlm 2014-05-23 06:30:58

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())
5
répondu WolfRage 2012-06-12 11:31:43

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.

4
répondu phihag 2011-06-23 11:04:19

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)]
4
répondu Ben Last 2012-04-30 00:32:34

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'])
4
répondu DarkXDroid 2014-02-13 03:32:21

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!

3
répondu user3712955 2014-06-11 22:44:30

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()
3
répondu RiccardoCh 2017-03-15 16:37:10

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).

2
répondu Etienne Perot 2012-04-26 00:32:06
import socket
socket.gethostbyname(socket.getfqdn())
2
répondu Oink 2012-06-08 09:42:20

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()
2
répondu Artur Barseghyan 2013-09-05 10:15:20
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.

2
répondu Ishwarya 2017-12-28 09:50:33