2013-04-29 18 views
5

w tej chwili robię:Niezawodnie dostać Adres IPv6 w Pythonie

def get_inet_ip(): 
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
    s.connect(('mysite.com', 80)) 
    return s.getsockname()[0] 

ta została oparta na: Finding local IP addresses using Python's stdlib

Jednak ta wygląda nieco wątpliwe. O ile mogę powiedzieć, otwiera gniazdo do mysite.com:80, a następnie zwraca pierwszy adres dla tego gniazda, zakładając, że jest to adres IPv4. Wydaje się to trochę podejrzane ... Nie sądzę, że kiedykolwiek możemy zagwarantować, że tak będzie.

To moje pierwsze pytanie, czy jest to bezpieczne? Na serwerze obsługującym IPv6, czy adres IPv6 może zostać nieoczekiwanie zwrócony?

Moje drugie pytanie brzmi: w jaki sposób uzyskać adres IPv6 w podobny sposób. Zamierzam zmodyfikować funkcję, aby pobrać opcjonalny parametr ipv6.

+0

to nie jest wiarygodną metodą dla IPv4 . –

+0

Tak, nie myślałem. Proszę wyjaśnij dalej. –

Odpowiedz

1

Należy używać funkcji socket.getaddrinfo()

Przykład kodu dostać IPv6

def get_ip_6(host,port=80): 
    # discard the (family, socktype, proto, canonname) part of the tuple 
    # and make sure the ips are unique 
    alladdr = list(
     set(
      map(
       lambda x: x[4], 
       socket.getaddrinfo(host,port) 
      ) 
     ) 
    ) 
    ip6 = filter(
     lambda x: ':' in x[0], # means its ip6 
     alladdr 
    ) 
    return ip6 
+0

Byłoby lepiej filtrować dla pola adresu rodziny wyniku, a nie dla tekstowej represie zwróconego adresu. Zobacz moją odpowiedź. – glglgl

+0

Czy lambdas itp. ... będą działać w wersji 2.4? To musi być kompatybilne. –

+0

@glglgl Tak, masz rację, to był tylko szybki i brudny przykład. Chodziło głównie o przekierowanie go do dokumentacji socket.getaddrinfo(). – katharas

6

Pytanie brzmi, czy po prostu chcesz się połączyć, czy naprawdę chcesz adres?

Jeśli tylko chcesz się połączyć, można zrobić

s = socket.create_connection(('mysite.com', 80)) 

i mieć połączenie ustanowione.

Jednakże, jeśli jesteś zainteresowany w adresie, można przejść jeden z następujących sposobów:

def get_ip_6(host, port=0): 
    import socket 
    # search only for the wanted v6 addresses 
    result = socket.getaddrinfo(host, port, socket.AF_INET6) 
    return result # or: 
    return result[0][4][0] # just returns the first answer and only the address 

lub, aby być bliżej another, already presented solution:

def get_ip_6(host, port=0): 
    # search for all addresses, but take only the v6 ones 
    alladdr = socket.getaddrinfo(host,port) 
    ip6 = filter(
     lambda x: x[0] == socket.AF_INET6, # means its ip6 
     alladdr 
    ) 
    # if you want just the sockaddr 
    # return map(lambda x:x[4],ip6) 
    return list(ip6)[0][4][0] 
+0

Tak, chcę IP, aby przejść do pliku konfiguracyjnego. –