Pergunta

Como posso encontrar os endereços IP locais (ou seja 192.168.x.x ou 10.0.x.x) em plataforma Python de forma independente e usando apenas a biblioteca padrão?

Foi útil?

Solução

import socket
socket.gethostbyname(socket.gethostname())

Isso não vai funcionar sempre (retornos 127.0.0.1 em máquinas que têm o nome da máquina em /etc/hosts como 127.0.0.1), um paliativo seria o que GIMEL mostra, uso socket.getfqdn() vez. Claro que sua máquina precisa de um nome de host resolvido.

Outras dicas

Eu encontrei este mas parece um pouco hackish, mas eles dizem que tentou fazê-lo em * nix e eu fiz em janelas e funcionou.

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
print(s.getsockname()[0])
s.close()

Esta pressupõe que você tenha um acesso à Internet, e que não existe uma proxy local.

Esse método retorna o "primário" IP na caixa local (aquele com uma rota padrão) .

  • não precisa de acesso à rede roteáveis ??ou qualquer ligação em tudo.
  • funciona mesmo se todas as interfaces estão desconectados da rede.
  • não precisa ou até mesmo tentar obter em qualquer outro lugar .
  • Funciona com NAT, público, privado externo e
  • do IP interno
  • puro Python 2 (ou 3) sem dependências externas.
  • funciona em Linux, Windows e 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

Isso retorna um único IP, que é a principal (aquele com uma rota padrão). Se você precisa, em vez tudo de IP ligado a todas as interfaces (incluindo localhost, etc), consulte esta resposta .

Se você está atrás de um firewall NAT como sua caixa de wi-fi em casa, então isso não vai mostrar o seu IP público NAT, mas em vez disso o seu IP NAT privado na rede local que tem uma rota padrão para o roteador Wi-Fi local; ficando IP externo do seu router wi-fi seria ou exigem executando isso em que a caixa, ou se conectar a um serviço externo, como whatismyip.com/whatismyipaddress.com que poderia refletir de volta o IP ... mas isso é completamente diferente da pergunta original. :)

Atualizado connect) chamada (por sugestão de Pedro nos comentários. (Se você precisar de uma declaração licença específica, este é de domínio público / gratuito para qualquer uso, ou MIT / CC2-BY-SA por código de estouro de pilha / licença de conteúdo em sua opção.)

Como um alias chamado myip, que deve funcionar em todos os lugares:

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])'"
  • funciona corretamente com Python 2.x, Python 3.x, moderna e distribuições Linux antigos, OSX / MacOS e Windows para encontrar o endereço IPv4 atual.
  • Não vai devolver o resultado correcto para máquinas com múltiplos endereços IP, IPv6, o endereço IP não configurado ou nenhum acesso à Internet.

O mesmo que acima, mas apenas o código 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])
  • Isto irá lançar uma exceção se nenhum endereço IP está configurado.

versão que irá também trabalhar em LANs sem conexão com a 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])

(graças @ccpizza )


Fundo :

Usando socket.gethostbyname(socket.gethostname()) não funcionou aqui, porque um dos computadores que eu estava em teve um /etc/hosts com entradas duplicadas e referências a si mesmo. socket.gethostbyname() só retorna a última entrada na /etc/hosts.

Esta foi a minha primeira tentativa, o que elimina todos os endereços começando com "127.":

import socket
print([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith("127.")][:1])

Isso funciona com o Python 2 e 3, em Linux e Windows, mas não lida com vários dispositivos de rede ou IPv6. No entanto, ele parou de funcionar em distros recentes do Linux, então eu tentei esta técnica alternativa ao invés. Ele tenta se conectar ao servidor do Google DNS em 8.8.8.8 em 53 port:

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

Então eu combinei os dois acima técnicas em um one-liner que devem funcionar em todos os lugares, e criou o alias myip e Python trecho no topo desta resposta.

Com a crescente popularidade do IPv6, e para servidores com múltiplas interfaces de rede, usando um módulo Python de terceiros para encontrar o endereço IP é provavelmente tanto mais robusta e confiável do que qualquer um dos métodos listados aqui.

Você pode usar o netifaces módulo. Basta digitar:

pip install netifaces

no seu shell de comando e ele irá instalar-se em instalação padrão Python.

Em seguida, você pode usá-lo como este:

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

No meu computador-lo impresso:

{45639BDC-1050-46E0-9BE9-075C30DE1FBC}: 192.168.0.100
{D43A468B-F3AE-4BF9-9391-4863A4500583}: 10.5.9.207

autor deste módulo reivindicações que deve funcionar em Windows, UNIX e Mac OS X.

método Socket API

https://stackoverflow.com/a/28950776/711085

Desvantagens:

  • Não multi-plataforma.
  • Requer código mais fallback, ligada à existência de endereços particulares na internet
  • Este também não trabalho se você está atrás de um NAT
  • Provavelmente cria uma conexão UDP, não é independente de (geralmente de ISP) disponibilidade DNS (veja outras respostas para idéias como usar 8.8.8.8: Google (coincidentemente também DNS))
  • Certifique-se de fazer o endereço de destino inacessível, como um endereço IP numérico que é especificação-garantido para ser utilizada. Não use algum domínio como fakesubdomain.google.com ou somefakewebsite.com; você ainda vai estar a enviar spam que o partido (agora ou no futuro), e spamming seus próprios caixas da rede, bem como no processo.

método Refletor

(Note que isso não responder à pergunta do OP do endereço IP local, por exemplo 192.168 ...;. Que lhe dá o seu endereço IP público, que pode ser mais desejável dependendo de caso de uso)

Você pode consultar algum site como whatismyip.com (mas com uma API), tais como:

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 se estiver usando 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)

Vantagens:

  • Uma vantagem deste método é que é cross-platform
  • Ele funciona por trás NAT feias (por exemplo, seu roteador doméstico).

Desvantagens (e soluções):

  • Requer este site para ser instalado, o formato a não mudança (quase certamente não), e seus servidores DNS estar funcionando. Um pode atenuar este problema também consultar outros refletores de terceiros de endereços IP em caso de falha.
  • possível vetor de ataque se você não consulta várias refletores (para evitar um refletor comprometida de dizer-lhe que o seu endereço é algo que não é), ou se você não usa HTTPS (para evitar a man-in-the- ataque do meio fingindo ser o servidor)

editar : Embora inicialmente eu pensei que estes métodos eram muito ruim (a menos que você use muitos fallbacks, o código pode ser irrelevante muitos anos a partir de agora), ele não colocar a questão "o que é a internet? ". Um computador pode ter muitas interfaces que apontam para muitas redes diferentes. Para uma descrição mais completa do tema, google para gateways and routes. Um computador pode ser capaz de acessar uma rede interna através de um gateway interno, ou acessar a web em todo o mundo através de um gateway por exemplo, um roteador (geralmente o caso). O endereço IP local que o OP pergunta sobre só é bem definida em relação a uma única camada link, então você tem que especificar que ( "é a placa de rede ou o cabo de ethernet, o que estamos falando?") . Pode haver várias respostas não-exclusivo para esta questão colocada. No entanto, o endereço de IP global sobre a world wide web é provavelmente bem definida (na ausência de enorme fragmentação da rede.): Provavelmente o caminho de retorno através do gateway que pode acessar o TLDs

Se o computador tem uma rota para a Internet, esta vontade sempre trabalho para obter o endereço IP local preferido, mesmo que / etc / hosts não está definido corretamente.

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]

No 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 usando módulo seguinte:

#!/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

testado com o Windows e Linux (e não requer módulos adicionais para aqueles) destina para uso em sistemas que estão em uma única LAN baseada IPv4.

A lista fixa de nomes de interface não funciona para versões do Linux recentes, que adotam a mudança V197 systemd sobre nomes de interface previsíveis como fora apontado por Alexander . Nesses casos, você precisa substituir manualmente a lista com os nomes de interface no seu sistema, ou utilizar outra solução como netifaces .

Eu uso isso em minhas máquinas ubuntu:

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

Isso não funciona.

Se você não quiser usar pacotes externos e não quer contar com servidores de Internet fora, isso pode ajudar. É um exemplo de código que eu encontrei na Google Code Search e modificado para retornar as informações necessárias:

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

Uso:

>>> for addr in getIPAddresses():
>>>    print addr
192.168.0.100
10.5.9.207

Como ele se baseia em windll, isso vai funcionar apenas no Windows.

A versão que eu não acredito que ainda não foi publicado. Eu testei com Python 2.7 no Ubuntu 12.04.

Encontrado esta solução em: 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])

Exemplo Resultado:

>>> get_ip_address('eth0')
'38.113.228.130'

No Debian (testado) e eu suspeito que a maioria do Linux ..

import commands

RetMyIP = commands.getoutput("hostname -I")

No MS Windows (testado)

import socket

socket.gethostbyname(socket.gethostname())

Variação na resposta de ninjagecko. Isto deve funcionar em qualquer rede local que permite UDP transmissão e não requer acesso a um endereço na LAN 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())

Eu tenho medo que não existem quaisquer formas independentes boa plataforma para fazer isso além de se conectar a outro computador e ter que enviar-lhe o seu endereço IP. Por exemplo: findmyipaddress . Note que isto não vai funcionar se você precisa de um endereço IP que está por trás de NAT a menos que o computador que você está se conectando está por trás NAT também.

Aqui está uma solução que funciona em Linux: obter o endereço IP associado a uma interface de rede .

Uma maneira simples de produzir uma saída "limpa" via utils linha de comando:

import commands
ips = commands.getoutput("/sbin/ifconfig | grep -i \"inet\" | grep -iv \"inet6\" | " +
                         "awk {'print $2'} | sed -ne 's/addr\:/ /p'")
print ips

Ela vai mostrar todos os endereços IPv4 no sistema.

FYI eu posso verificar que o método:

import socket
addr = socket.gethostbyname(socket.gethostname())

Obras em OS X (10.6,10.5), Windows XP, e no servidor do departamento de RHEL bem administrada. Não funcionou em um muito mínima CentOS VM que eu simplesmente fazer alguma semente hackear. Assim, para que exemplo você pode apenas verificar para um endereço 127.0.0.1 e, nesse caso, faça o seguinte:

if addr == "127.0.0.1":
     import commands
     output = commands.getoutput("/sbin/ifconfig")
     addr = parseaddress(output)

E, em seguida, analisar o endereço IP a partir da saída. Deve-se notar que ifconfig não é no trajeto de um usuário normal por padrão e é por isso que eu dou o caminho completo no comando. Espero que isso ajude.

Esta é uma variante da resposta de Unkwntech - ele fornece uma função get_local_addr(), que retorna o endereço do hospedeiro a principal LAN ip. Estou postando isso porque isso acrescenta uma série de coisas:. Suporte IPv6, manipulação de erro, ignorando localhost / addrs LINKLOCAL, e usa um endereço TESTNET (rfc5737) para se conectar ao

# 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

Isto irá funcionar na maioria das caixas de 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)]

Esta resposta é a minha tentativa pessoal para resolver o problema de conseguir o IP LAN, desde socket.gethostbyname(socket.gethostname()) também retornou 127.0.0.1. Este método não requer Internet apenas uma conexão LAN. Código é para Python 3.x, mas poderia ser facilmente convertida para 2.x. Usando UDP Transmissão:

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 é seu endereço IP real. De um modo geral, um computador pode ter qualquer número de endereços IP. Você pode filtrá-los para redes privadas -. 127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12 e 192.168.0.0/16

No entanto, não há nenhuma maneira de plataforma cruzada para obter todos os endereços IP. No Linux, você pode usar o SIOCGIFCONF ioctl.

endereços

Um ligeiro refinamento da versão comandos que usa o comando IP, e retorna IPv4 e 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)]

Bem, você pode usar o comando "ip route" no GNU / Linux a conhecer o seu endereço IP atual.

Isto mostra o IP indicados para a interface pelo servidor DHCP em execução no router / modem. Normalmente "192.168.1.1/24" é o IP para a rede local onde "24", a gama de endereços IP posible dadas pelo servidor DHCP dentro do intervalo de máscara.

Aqui está um exemplo: Note que PyNotify é apenas um complemento para obter o meu ponto reto e não é necessário em tudo

#! /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()    

A vantagem disso é que você não precisa especificar a interface de rede. Isso é muito útil quando executando um servidor de soquete

Você pode instalar PyNotify usando easy_install ou mesmo Pip:

easy_install py-notify

ou

pip install py-notify

ou dentro script python / intérprete

from pip import main

main(['install', 'py-notify'])

Nota:. Isto não está usando a biblioteca padrão, mas bastante simples

$ pip instalar pif

from pif import get_public_ip
get_public_ip()

netifaces está disponível através do pip e easy_install. (Eu sei, não é na base, mas pode valer a pena o instalar.)

netifaces tem algumas esquisitices em várias plataformas:

  • A interface localhost / loop-back pode não ser sempre incluído (Cygwin).
  • Os endereços são listados por-protocolo (por exemplo, o IPv4, IPv6) e protocolos estão listados por interface. Em alguns sistemas (Linux) cada par protocolo de interface tem sua própria interface associada (usando o interface_name: n notação), enquanto em outros sistemas (Windows) uma única interface terá uma lista de endereços para cada protocolo. Em ambos os casos, há uma lista de protocolos, mas pode conter apenas um único elemento.

Aqui está um código de netifaces de jogar com:

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.

O código acima não mapeia uma volta endereço para o seu nome de interface (útil para gerar ebtables / iptables regras em tempo real). Então aqui está uma versão que mantém as informações acima com o nome da interface em uma tupla:

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]

E, não, eu não estou apaixonado por compreensões lista. É apenas a forma como o meu cérebro funciona nos dias de hoje.

O trecho a seguir irá imprimir tudo para fora:

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)

Aproveite!

Para obter o endereço IP você pode usar um comando shell directamente na python :

import socket, subprocess

def getIpAndHostname():
    hostname =  socket.gethostname()

    shell_cmd = "ifconfig | awk '/inet addr/{print substr($2,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()
import netifaces as ni 

ni.ifaddresses('eth0')
ip = ni.ifaddresses('eth0')[ni.AF_INET][0]['addr']
print(ip)

Isso irá retornar o endereço IP no sistema Ubuntu, bem como MacOS. A saída será o endereço IP do sistema como como meu IP:. 192.168.1.10

Se você está procurando uma diferente endereço IPv4 do seu localhost endereço IP 127.0.0.1, aqui é uma peça elegante de códigos Python:

import subprocess
address = subprocess.check_output(['hostname', '-s', '-I'])
address = address.decode('utf-8') 
address=address[:-1]

O que também pode ser escrito em uma única linha:

address = subprocess.check_output(['hostname', '-s', '-I']).decode('utf-8')[:-1]

Mesmo se você colocar localhost em /etc/hostname, o código irá ainda dar o seu endereço IP local.

Eu tive que resolver o problema "Descobrir se um endereço IP é local ou não", e meu primeiro pensamento foi para construir uma lista de IPs que eram local e, em seguida, o jogo contra ele. Isto é o que me levou a esta pergunta. No entanto, mais tarde percebi que há uma maneira mais straightfoward fazê-lo:. Tentar vincular em que IP e ver se funciona

_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

Eu sei que isto não responde a pergunta diretamente, mas isso deve ser útil para qualquer um que tenta resolver a questão conexa e que estava seguindo a mesma linha de pensamento. Isto tem a vantagem de ser uma solução multi-plataforma (eu acho).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top