Domanda

Sto lavorando per creare una semplice applicazione server con Python e sto cercando di ottenere l'IP a cui collegare il socket di ascolto. Un esempio che ho visto usa questo:

HOST = gethostbyaddr(gethostname())

Con un po 'più di elaborazione dopo questo, dovrebbe darmi solo l'IP host come una stringa. Questo dovrebbe restituire l'indirizzo IPv4. Ma quando eseguo questo codice, restituisce il mio indirizzo IPv6. Perché lo fa e come posso ottenere il mio indirizzo IPv4?

Se è pertinente, sto usando Windows Vista e Python 2.5

È stato utile?

Soluzione

Ottenere il tuo indirizzo IP è più difficile di quanto pensi.

Controlla questa risposta ho dato per l'unico modo affidabile che ho trovato.

Ecco cosa dice la risposta nel caso in cui non ti piace fare clic sulle cose:

Utilizza il modulo netifaces . Poiché la rete è complessa, l'utilizzo di netifaces può essere un po 'complicato, ma ecco come fare quello che vuoi:

>>> import netifaces
>>> netifaces.interfaces()
['lo', 'eth0']
>>> netifaces.ifaddresses('eth0')
{17: [{'broadcast': 'ff:ff:ff:ff:ff:ff', 'addr': '00:11:2f:32:63:45'}], 2: [{'broadcast': '10.0.0.255', 'netmask': '255.255.255.0', 'addr': '10.0.0.2'}], 10: [{'netmask': 'ffff:ffff:ffff:ffff::', 'addr': 'fe80::211:2fff:fe32:6345%eth0'}]}
>>> for interface in netifaces.interfaces():
...   print netifaces.ifaddresses(interface)[netifaces.AF_INET]
...
[{'peer': '127.0.0.1', 'netmask': '255.0.0.0', 'addr': '127.0.0.1'}]
[{'broadcast': '10.0.0.255', 'netmask': '255.255.255.0', 'addr': '10.0.0.2'}]
>>> for interface in netifaces.interfaces():
...   for link in netifaces.ifaddresses(interface)[netifaces.AF_INET]:
...     print link['addr']
...
127.0.0.1
10.0.0.2

Questo può essere reso un po 'più leggibile in questo modo:

from netifaces import interfaces, ifaddresses, AF_INET

def ip4_addresses():
    ip_list = []
    for interface in interfaces():
        for link in ifaddresses(interface)[AF_INET]:
            ip_list.append(link['addr'])
    return ip_list

Se desideri indirizzi IPv6, usa AF_INET6 invece di AF_INET . Se ti stai chiedendo perché netifaces utilizza elenchi e dizionari ovunque, è perché un singolo computer può avere più schede di rete e ogni scheda di rete può avere più indirizzi e ogni indirizzo ha il proprio set di opzioni .

Altri suggerimenti

IPv6 ha la precedenza su IPv4 poiché è la famiglia più recente, in genere è ciò che si desidera se il nome host è associato a più famiglie. Dovresti utilizzare getaddrinfo per una risoluzione indipendente dalla famiglia, ecco un esempio,

import sys, socket;
host = socket.gethostname();
result = socket.getaddrinfo(host, None);
print "family:%i socktype:%i proto:%i canonname:%s sockaddr:%s"%result[0];
result = socket.getaddrinfo(host, None, socket.AF_INET);
print "family:%i socktype:%i proto:%i canonname:%s sockaddr:%s"%result[0];
result = socket.getaddrinfo(host, None, socket.AF_INET6);
print "family:%i socktype:%i proto:%i canonname:%s sockaddr:%s"%result[0];

Che su un host configurato dual-stack mi dà quanto segue,

family:10 socktype:1 proto:6 canonname: sockaddr:('2002:dce8:d28e::31', 0, 0, 0)
family:2 socktype:1 proto:6 canonname: sockaddr:('10.6.28.31', 0)
family:10 socktype:1 proto:6 canonname: sockaddr:('2002:dce8:d28e::31', 0, 0, 0)

gethostbyaddr () accetta un indirizzo IP come parametro, non un nome host, quindi sono sorpreso che funzioni affatto senza generare un'eccezione. Se invece intendevi gethostbyname () , quindi i tuoi risultati sono più sorprendenti, dal momento che quella funzione afferma di non supportare IPv6. La risposta di Harley spiega come ottenere correttamente il tuo indirizzo IP.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top