Jak mogę znaleźć lokalne adresy IP (tj. 192.168.xx lub 10.0.xx) na platformie Python niezależnie i używając tylko standardowej biblioteki?
python
networking
ip-address
UnkwnTech
źródło
źródło
ifconfig -a
i użyj danych stamtąd ...ip addr
jest on o wiele bardziej odpowiedni (i łatwiej go analizować, uruchamiać).bind
gniazda określonego interfejsu, jest to kwestia zasad. Jeśli lokalny adres IP jest potrzebny do przekazania go peerowi, aby peer mógł „oddzwonić”, tj. W celu ponownego nawiązania połączenia z maszyną lokalną, sytuacja zależy od tego, czy istnieje NAT (translacja adresów sieciowych) pola pomiędzy. Jeśli nie ma NAT,getsockname
to dobry wybór.Odpowiedzi:
Nie zawsze będzie to działać (zwraca
127.0.0.1
na komputerach z nazwą hosta w/etc/hosts
as127.0.0.1
), paliative byłby tym, co pokazuje gimel, użyjsocket.getfqdn()
zamiast tego. Oczywiście twój komputer potrzebuje rozpoznawalnej nazwy hosta.źródło
socket.gethostbyname_ex(socket.gethostname())[-1]
Właśnie to znalazłem, ale wydaje się to trochę hackingowe, ale mówią, że wypróbowałem to na * nix, a ja zrobiłem na Windowsie i zadziałało.
Zakłada się, że masz dostęp do Internetu i nie ma lokalnego serwera proxy.
źródło
Ta metoda zwraca „podstawowy” adres IP w lokalnym polu (tym z domyślną trasą) .
Python 3 lub 2:
Zwraca pojedynczy adres IP, który jest podstawowy (ten z domyślną trasą). Jeśli zamiast tego potrzebujesz wszystkich adresów IP dołączonych do wszystkich interfejsów (w tym localhost itp.), Zapoznaj się z tą odpowiedzią .
Jeśli jesteś w domu za firewallem NAT, takim jak WiFi box, to nie pokaże twojego publicznego adresu IP NAT, ale twój prywatny adres IP w sieci lokalnej, która ma domyślną trasę do lokalnego routera WIFI; uzyskanie zewnętrznego adresu IP routera Wi-Fi wymagałoby uruchomienia tego na tym polu lub połączenia się z usługą zewnętrzną, taką jak whatismyip.com/whatismyipaddress.com, która może odzwierciedlać adres IP ... ale to zupełnie inne pytanie niż pierwotne. :)
źródło
socket.gethostbyname(socket.gethostname())
daje okropne wyniki.Jako alias
myip
, powinien działać wszędzie:To samo co powyżej, ale tylko kod Python:
Wersja, która będzie działać również w sieciach LAN bez połączenia z Internetem:
(dzięki @ccpizza )
Tło :
Korzystanie
socket.gethostbyname(socket.gethostname())
nie działało tutaj, ponieważ jeden z komputerów, na których byłem, miał/etc/hosts
zduplikowane wpisy i odniesienia do siebie.socket.gethostbyname()
zwraca tylko ostatni wpis w/etc/hosts
.To była moja pierwsza próba usunięcia wszystkich adresów zaczynających się od
"127."
:Działa to z Pythonem 2 i 3 w systemach Linux i Windows, ale nie obsługuje kilku urządzeń sieciowych ani IPv6. Jednak przestał działać na ostatnich dystrybucjach Linuksa, więc zamiast tego spróbowałem tej alternatywnej techniki. Próbuje połączyć się z serwerem Google DNS
8.8.8.8
na porcie53
:Następnie połączyłem dwie powyższe techniki w jedną linijkę, która powinna działać wszędzie, i
myip
na początku tej odpowiedzi utworzyłem alias i fragment kodu w języku Python.Wraz ze wzrostem popularności protokołu IPv6 oraz w przypadku serwerów z wieloma interfejsami sieciowymi korzystanie z zewnętrznego modułu Python do znajdowania adresu IP jest prawdopodobnie bardziej niezawodne i niezawodne niż którakolwiek z wymienionych tutaj metod.
źródło
socket.getaddrinfo()
powinna działać konsekwentnie na różnych platformach - ale sprawdziłem to tylko w systemie Linux, nie zawracałem sobie głowy innymi systemami./etc/resolve.conf: No such file or directory
i mam lokalny adres IPv4 pokazany przezifconfig
.Możesz użyć modułu netifaces . Po prostu wpisz:
w twojej powłoce poleceń i zainstaluje się na domyślnej instalacji Pythona.
Następnie możesz użyć tego w następujący sposób:
Na moim komputerze wydrukowano:
Autor tego modułu twierdzi, że powinien działać w systemach Windows, UNIX i Mac OS X.
źródło
Metoda interfejsu API gniazda
patrz https://stackoverflow.com/a/28950776/711085
Wady:
Metoda odbłyśnika
(Pamiętaj, że nie odpowiada to na pytanie OP dotyczące lokalnego adresu IP, np. 192.168 ...; daje ci twój publiczny adres IP, który może być bardziej pożądany w zależności od przypadku użycia).
Możesz wysłać zapytanie do niektórych witryn, takich jak whatismyip.com (ale z interfejsem API), takich jak:
lub jeśli używasz python2:
Zalety:
Wady (i obejścia):
edytuj : Chociaż początkowo myślałem, że te metody były naprawdę złe (chyba że użyjesz wielu awaryjnych metod, kod może być nieistotny za wiele lat od teraz), stawia pytanie „co to jest internet?”. Komputer może mieć wiele interfejsów wskazujących wiele różnych sieci. Aby uzyskać dokładniejszy opis tego tematu, odwiedź Google for
gateways and routes
. Komputer może być w stanie uzyskać dostęp do sieci wewnętrznej za pośrednictwem wewnętrznej bramy lub uzyskać dostęp do sieci światowej za pośrednictwem bramy na przykład na routerze (zwykle tak jest). Lokalny adres IP, o który prosi OP, jest dobrze zdefiniowany tylko w odniesieniu do pojedynczej warstwy łącza, więc musisz to określić („czy to karta sieciowa, czy kabel Ethernet, o którym mówimy?”) . Może być wiele niejednoznacznych odpowiedzi na postawione pytanie. Jednak globalny adres IP w sieci WWW jest prawdopodobnie dobrze zdefiniowany (przy braku znacznego rozdrobnienia sieci): prawdopodobnie ścieżka powrotna przez bramę, która może uzyskać dostęp do TLD.źródło
Jeśli komputer ma trasę do Internetu, zawsze będzie działać, aby uzyskać preferowany lokalny adres IP, nawet jeśli / etc / hosts nie jest ustawiony poprawnie.
źródło
8.8.8.8
czy serwer Google dns możemy to zrobić z lokalnym serwerem dns?W systemie Linux:
źródło
ioctl
). Gniazdo nie jest powiązane z interfejsem, o którym chcesz uzyskać informacje o adresatach - to tylko mechanizm komunikacji między przestrzenią użytkownika a jądrem. en.wikipedia.org/wiki/Ioctl lxr.free-electrons.com/source/net/socket.cstruct.pack('16sH14s', iface, socket.AF_INET, '\x00'*14)
należy go zastąpićstruct.pack('16sH14s', iface.encode('utf-8'), socket.AF_INET, b'\x00'*14)
ioctl
jest starszym interfejsem. Nie sądzę, że obsługuje IPv6 i prawdopodobnie nigdy nie będzie. Myślę, że „właściwą” drogą jest Netlink, co nie jest bardzo proste w Pythonie. Myślę, że libc powinien mieć funkcję, dogetifaddrs
której można uzyskać dostęp poprzezctypes
moduł pytonów , który może działać - man7.org/linux/man-pages/man3/getifaddrs.3.htmlużywam następującego modułu:
Testowany z Windows i Linuxem (i nie wymaga dodatkowych modułów) przeznaczony do użytku w systemach, które są w jednej sieci LAN opartej na IPv4.
Naprawiona lista nazw interfejsów nie działa w najnowszych wersjach systemu Linux, które przyjęły zmianę systemd v197 dotyczącą przewidywalnych nazw interfejsów, jak wskazał Alexander . W takich przypadkach należy ręcznie zastąpić listę nazwami interfejsów w systemie lub użyć innego rozwiązania, takiego jak netifaces .
źródło
enp0s25
. Aby uzyskać więcej informacji, zobacz wiki.archlinux.org/index.php/Network_Configuration#Device_namesstruct.pack('256s', bytes(ifname[:15]))
Używam tego na moich maszynach Ubuntu:
To nie działa
źródło
Jeśli nie chcesz korzystać z zewnętrznych pakietów i nie chcesz polegać na zewnętrznych serwerach internetowych, może to pomóc. To przykładowy kod, który znalazłem w Google Code Search i zmodyfikowałem, aby zwrócić wymagane informacje:
Stosowanie:
Jak się opiera
windll
, działa to tylko w systemie Windows.źródło
Na Debianie (testowane) i podejrzewam, że większość Linuksa ..
W systemie MS Windows (testowane)
źródło
hostname: illegal option -- I\nusage: hostname [-fs] [name-of-host]
Wersja, której nie wierzę, została jeszcze opublikowana. Testowałem z Pythonem 2.7 na Ubuntu 12.04.
Znaleziono to rozwiązanie na stronie : http://code.activestate.com/recipes/439094-get-the-ip-address-associated-with-a-network-inter/
Przykład wyniku:
źródło
Wariacja na temat odpowiedzi ninja. Powinno to działać w każdej sieci LAN, która umożliwia transmisję UDP i nie wymaga dostępu do adresu w sieci LAN ani w Internecie.
źródło
<broadcast>
poprawna nazwa hosta? !! Ile takich słownych nazw hostów jest poprawnych?Obawiam się, że nie ma innych dobrych sposobów na niezależne od platformy, niż połączenie się z innym komputerem i wysłanie ci adresu IP. Na przykład: findmyipaddress . Pamiętaj, że to nie zadziała, jeśli potrzebujesz adresu IP spoza NAT, chyba że komputer, z którym się łączysz, również ma NAT.
Oto jedno rozwiązanie, które działa w systemie Linux: uzyskaj adres IP powiązany z interfejsem sieciowym .
źródło
Jednym prostym sposobem na uzyskanie „czystego” wyjścia za pomocą narzędzi wiersza poleceń:
Wyświetli wszystkie adresy IPv4 w systemie.
źródło
Do Twojej wiadomości mogę zweryfikować, czy metoda:
Działa w OS X (10.6,10.5), Windows XP i na dobrze administrowanym serwerze działu RHEL. Nie działało na bardzo minimalnej maszynie Wirtualnej CentOS, na której po prostu hakowałem jądro. W tym przypadku możesz po prostu sprawdzić adres 127.0.0.1 i w takim przypadku wykonaj następujące czynności:
Następnie przeanalizuj adres IP z wyjścia. Należy zauważyć, że ifconfig domyślnie nie znajduje się w PATH normalnego użytkownika i dlatego podaję pełną ścieżkę w poleceniu. Mam nadzieję, że to pomoże.
źródło
Jest to wariant odpowiedzi UnkwnTech - zapewnia
get_local_addr()
funkcję, która zwraca podstawowy adres IP LAN hosta. Publikuję to, ponieważ dodaje to wiele rzeczy: obsługę ipv6, obsługę błędów, ignorowanie adresatów localhost / linklocal i użycie adresu TESTNET (rfc5737) do połączenia.źródło
None
get_local_addr(remove="www.google.com")
zwraca coś takiego ? Rejestrowaniesocket.error
wyrzuconego przez _get_local_addr () może pomóc w diagnostyce.źródło
['fe80::34e8:fe19:1459:2cde%22','fe80::d528:99fb:d572:e289%12', '192.168.56.1', '192.168.1.2']
na pulpicie Windows.Działa to na większości pudełek z Linuksem:
źródło
Ta odpowiedź jest moją osobistą próbą rozwiązania problemu uzyskania adresu IP sieci LAN, ponieważ
socket.gethostbyname(socket.gethostname())
zwrócił również 127.0.0.1. Ta metoda nie wymaga Internetu tylko połączenia LAN. Kod dotyczy Pythona 3.x, ale można go łatwo przekonwertować na wersję 2.x. Korzystanie z emisji UDP:źródło
127.0.1.1
jest twój prawdziwy adres IP. Mówiąc bardziej ogólnie, komputer może mieć dowolną liczbę adresów IP. Możesz je filtrować dla sieci prywatnych - 127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12 i 192.168.0.0/16.Jednak nie ma wieloplatformowego sposobu uzyskania wszystkich adresów IP. W systemie Linux możesz użyć
SIOCGIFCONF
ioctl.źródło
Nieznaczne udoskonalenie wersji poleceń, która korzysta z polecenia IP i zwraca adresy IPv4 i IPv6:
źródło
Cóż, możesz użyć polecenia „ip route” w systemie GNU / Linux, aby poznać swój aktualny adres IP.
Pokazuje adres IP nadany interfejsowi przez serwer DHCP działający na routerze / modemie. Zwykle „192.168.1.1/24” to adres IP sieci lokalnej, gdzie „24” oznacza zakres możliwych adresów IP podanych przez serwer DHCP w zakresie maski.
Oto przykład: Zauważ, że PyNotify to tylko dodatek, aby wyprostować mój punkt i wcale nie jest wymagany
Zaletą tego jest to, że nie trzeba określać interfejsu sieciowego. Jest to bardzo przydatne podczas uruchamiania serwera gniazd
Możesz zainstalować PyNotify za pomocą easy_install lub nawet Pip:
lub
lub w skrypcie / interpretatorze Pythona
źródło
Jeśli szukasz adresu IPV4 innego niż adres IP lokalnego hosta
127.0.0.1
, oto schludny kawałek kodów python:Które można również zapisać w jednym wierszu:
Nawet jeśli umieścić
localhost
w/etc/hostname
kod będzie nadal dać swój lokalny adres IP.źródło
Dla systemu Linux, można po prostu użyć
check_output
zhostname -I
poleceniem systemowym tak:źródło
Uwaga: To nie jest użycie standardowej biblioteki, ale dość proste.
$ pip install pif
źródło
netifaces jest dostępny poprzez pip i easy_install. (Wiem, że nie jest w bazie, ale może być wart instalacji).
netifaces ma pewne dziwactwa na różnych platformach:
Oto kod netifaces do zabawy:
Powyższy kod nie odwzorowuje adresu z powrotem na nazwę interfejsu (przydatne do generowania reguł ebtables / iptables w locie). Oto wersja, która przechowuje powyższe informacje z nazwą interfejsu w krotce:
I nie, nie jestem zakochana w listach. Tak właśnie działa mój mózg.
Poniższy fragment kodu wydrukuje wszystko:
Cieszyć się!
źródło
Wersja Python 3.4 wykorzystująca nowo wprowadzony pakiet asyncio.
Jest to oparte na doskonałej odpowiedzi UnkwnTech .
źródło
Aby uzyskać adres IP, możesz użyć polecenia powłoki bezpośrednio w python :
źródło