Bagaimana saya bisa menemukan alamat IP lokal (yaitu 192.168.xx atau 10.0.xx) dalam platform Python secara independen dan hanya menggunakan perpustakaan standar?
python
networking
ip-address
UnkwnTech
sumber
sumber
ifconfig -a
dan gunakan output dari sana ...ip addr
jauh lebih cocok (dan lebih mudah untuk mengurai, untuk boot).bind
soket ke antarmuka tertentu, maka itu adalah masalah kebijakan. Jika alamat IP lokal diperlukan untuk menyerahkannya ke peer sehingga peer dapat "menelepon kembali", yaitu untuk membuka koneksi kembali ke mesin lokal, maka situasinya tergantung pada apakah ada NAT (Terjemahan Alamat Jaringan) kotak di antara keduanya. Jika tidak ada NAT,getsockname
adalah pilihan yang baik.Jawaban:
Ini tidak akan bekerja selalu (mengembalikan
127.0.0.1
pada mesin yang memiliki nama host/etc/hosts
sebagai127.0.0.1
), paliative akan menjadi apa yang ditampilkan gimel, gunakansocket.getfqdn()
saja. Tentu saja mesin Anda membutuhkan nama host yang dapat diatasi.sumber
socket.gethostbyname_ex(socket.gethostname())[-1]
Saya baru saja menemukan ini tetapi tampaknya agak retas, tetapi mereka mengatakan mencobanya di * nix dan saya lakukan di windows dan berhasil.
Ini mengasumsikan Anda memiliki akses internet, dan bahwa tidak ada proxy lokal.
sumber
Metode ini mengembalikan IP "primer" pada kotak lokal (yang dengan rute default) .
Python 3 atau 2:
Ini mengembalikan satu IP yang merupakan primer (yang dengan rute default). Jika Anda membutuhkan semua IP yang terpasang pada semua antarmuka (termasuk localhost, dll), lihat jawaban ini .
Jika Anda berada di belakang firewall NAT seperti kotak wifi Anda di rumah, maka ini tidak akan menunjukkan IP NAT publik Anda, melainkan IP pribadi Anda di jaringan lokal yang memiliki rute default ke router WIFI lokal Anda; mendapatkan IP eksternal wifi router Anda akan mengharuskan menjalankan ini pada kotak ITU, atau menyambung ke layanan eksternal seperti whatismyip.com/whatismyipaddress.com yang dapat memantulkan kembali IP ... tapi itu sama sekali berbeda dari pertanyaan awal. :)
sumber
socket.gethostbyname(socket.gethostname())
memberikan hasil yang mengerikan.Sebagai alias dipanggil
myip
, itu harus bekerja di mana saja:Sama seperti di atas, tetapi hanya kode Python:
Versi yang juga akan berfungsi pada LAN tanpa koneksi internet:
(terima kasih @ccpizza )
Latar Belakang :
Penggunaan
socket.gethostbyname(socket.gethostname())
tidak berfungsi di sini, karena salah satu komputer yang saya gunakan memiliki/etc/hosts
entri duplikat dan referensi untuk dirinya sendiri.socket.gethostbyname()
hanya mengembalikan entri terakhir ke/etc/hosts
.Ini adalah upaya awal saya, yang menyingkirkan semua alamat yang dimulai dengan
"127."
:Ini berfungsi dengan Python 2 dan 3, di Linux dan Windows, tetapi tidak berurusan dengan beberapa perangkat jaringan atau IPv6. Namun, itu berhenti bekerja pada distro Linux baru-baru ini, jadi saya mencoba teknik alternatif ini sebagai gantinya. Mencoba menghubungkan ke server DNS Google di
8.8.8.8
at port53
:Lalu saya menggabungkan kedua teknik di atas menjadi satu-liner yang harus bekerja di mana-mana, dan menciptakan
myip
potongan alias dan Python di bagian atas jawaban ini.Dengan semakin populernya IPv6, dan untuk server dengan banyak antarmuka jaringan, menggunakan modul Python pihak ketiga untuk menemukan alamat IP mungkin lebih kuat dan dapat diandalkan daripada metode apa pun yang tercantum di sini.
sumber
socket.getaddrinfo()
harus bekerja secara konsisten di seluruh platform - tetapi saya hanya memeriksanya di Linux, tidak peduli tentang sistem operasi lain./etc/resolve.conf: No such file or directory
dan saya memiliki alamat IPv4 lokal yang ditunjukkan olehifconfig
.Anda dapat menggunakan modul netifaces . Ketik saja:
di shell perintah Anda dan itu akan menginstal sendiri pada instalasi Python default.
Maka Anda dapat menggunakannya seperti ini:
Di komputer saya itu dicetak:
Penulis modul ini mengklaim itu harus bekerja pada Windows, UNIX dan Mac OS X.
sumber
Metode Socket API
lihat https://stackoverflow.com/a/28950776/711085
Kerugian:
Metode reflektor
(Harap perhatikan bahwa ini tidak menjawab pertanyaan OP tentang alamat IP lokal, mis. 192.168 ...; ini memberi Anda alamat IP publik Anda, yang mungkin lebih diinginkan tergantung pada kasus penggunaan.)
Anda dapat menanyakan beberapa situs seperti whatismyip.com (tetapi dengan API), seperti:
atau jika menggunakan python2:
Keuntungan:
Kerugian (dan solusi):
sunting : Meskipun pada awalnya saya pikir metode ini benar-benar buruk (kecuali jika Anda menggunakan banyak fallback, kode mungkin tidak relevan bertahun-tahun dari sekarang), itu menimbulkan pertanyaan "apa itu internet?". Komputer mungkin memiliki banyak antarmuka yang menunjuk ke banyak jaringan yang berbeda. Untuk deskripsi topik yang lebih menyeluruh, google for
gateways and routes
. Komputer mungkin dapat mengakses jaringan internal melalui gateway internal, atau mengakses web di seluruh dunia melalui gateway misalnya router (biasanya casing). Alamat IP lokal yang ditanyakan OP hanya didefinisikan dengan baik sehubungan dengan satu lapisan tautan, jadi Anda harus menentukan bahwa ("apakah itu kartu jaringan, atau kabel ethernet, yang sedang kita bicarakan?") . Mungkin ada beberapa jawaban non-unik untuk pertanyaan ini sebagaimana diajukan. Namun alamat IP global di web di seluruh dunia mungkin didefinisikan dengan baik (tanpa adanya fragmentasi jaringan besar-besaran): mungkin jalur balik melalui gateway yang dapat mengakses TLD.sumber
Jika komputer memiliki rute ke Internet, ini akan selalu berfungsi untuk mendapatkan alamat ip lokal yang disukai, bahkan jika / etc / hosts tidak diatur dengan benar.
sumber
8.8.8.8
apakah server google dns dapatkah kita melakukannya dengan server dns lokal?Di Linux:
sumber
ioctl
). Soket tidak terikat antarmuka yang Anda inginkan addr info tentang - itu hanya mekanisme komunikasi antara userspace dan kernel. en.wikipedia.org/wiki/Ioctl lxr.free-electrons.com/source/net/socket.cstruct.pack('16sH14s', iface, socket.AF_INET, '\x00'*14)
harus diganti denganstruct.pack('16sH14s', iface.encode('utf-8'), socket.AF_INET, b'\x00'*14)
ioctl
adalah antarmuka lama yang saya tidak percaya mendukung IPv6 dan kemungkinan tidak akan pernah. Saya pikir cara yang 'Benar' adalah melalui Netlink yang tidak terlalu mudah dengan Python. Saya pikir libc harus memiliki fungsigetifaddrs
yang dapat diakses melaluictypes
modul python yang dapat berfungsi - man7.org/linux/man-pages/man3/getifaddrs.3.htmlSaya menggunakan modul berikut:
Diuji dengan windows dan linux (dan tidak memerlukan modul tambahan untuk mereka) yang dimaksudkan untuk digunakan pada sistem yang berada dalam LAN berbasis IPv4 tunggal.
Daftar tetap nama antarmuka tidak berfungsi untuk versi linux terbaru, yang telah mengadopsi perubahan systemd v197 tentang nama antarmuka yang dapat diprediksi seperti yang ditunjukkan oleh Alexander . Dalam kasus seperti itu, Anda perlu mengganti daftar secara manual dengan nama antarmuka pada sistem Anda, atau menggunakan solusi lain seperti netifaces .
sumber
enp0s25
. Untuk info lebih lanjut, lihat wiki.archlinux.org/index.php/Network_Configuration#Device_namesstruct.pack('256s', bytes(ifname[:15]))
Saya menggunakan ini di mesin ubuntu saya:
Ini tidak berhasil.
sumber
Jika Anda tidak ingin menggunakan paket eksternal dan tidak ingin bergantung pada server Internet luar, ini mungkin membantu. Ini adalah contoh kode yang saya temukan di Google Code Search dan dimodifikasi untuk mengembalikan informasi yang diperlukan:
Pemakaian:
Karena bergantung
windll
, ini hanya akan berfungsi pada Windows.sumber
Pada Debian (diuji) dan saya curiga kebanyakan Linux ..
Pada MS Windows (diuji)
sumber
hostname: illegal option -- I\nusage: hostname [-fs] [name-of-host]
Versi yang saya tidak percaya yang telah diposting. Saya diuji dengan python 2.7 di Ubuntu 12.04.
Menemukan solusi ini di: http://code.activestate.com/recipes/439094-get-the-ip-address-associated-with-a-network-inter/
Hasil Contoh:
sumber
Variasi pada jawaban ninjagecko. Ini harus bekerja pada LAN apa pun yang memungkinkan siaran UDP dan tidak memerlukan akses ke alamat di LAN atau internet.
sumber
<broadcast>
nama host yang valid? !! Berapa banyak dari nama host verbal ini yang valid?Saya khawatir tidak ada platform independen yang bagus untuk melakukan hal ini selain menghubungkan ke komputer lain dan mengirimkannya ke alamat IP Anda. Misalnya: findmyipaddress . Perhatikan bahwa ini tidak akan berfungsi jika Anda memerlukan alamat IP yang berada di belakang NAT kecuali komputer yang Anda sambungkan berada di belakang NAT.
Inilah salah satu solusi yang berfungsi di Linux: dapatkan alamat IP yang terkait dengan antarmuka jaringan .
sumber
Salah satu cara sederhana untuk menghasilkan output "bersih" melalui utilitas baris perintah:
Ini akan menampilkan semua alamat IPv4 pada sistem.
sumber
FYI Saya dapat memverifikasi bahwa metode:
Bekerja di OS X (10.6,10.5), Windows XP, dan pada server departemen RHEL yang dikelola dengan baik. Itu tidak bekerja pada CentOS VM yang sangat minim yang baru saja saya lakukan peretasan kernel. Jadi untuk contoh itu Anda bisa memeriksa alamat 127.0.0.1 dan dalam hal ini lakukan hal berikut:
Dan kemudian parsing alamat ip dari output. Perlu dicatat bahwa ifconfig tidak dalam PATH pengguna normal secara default dan itulah sebabnya saya memberikan path lengkap dalam perintah. Saya harap ini membantu.
sumber
Ini adalah varian dari jawaban UnkwnTech - ini menyediakan
get_local_addr()
fungsi, yang mengembalikan alamat IP LAN utama dari host. Saya mempostingnya karena ini menambahkan sejumlah hal: dukungan ipv6, penanganan kesalahan, mengabaikan localhost / linklocal addrs, dan menggunakan addr TESTNET (rfc5737) untuk terhubung.sumber
None
get_local_addr(remove="www.google.com")
pengembalian? Logging yangsocket.error
dilempar oleh _get_local_addr () mungkin membantu diagnosa.sumber
['fe80::34e8:fe19:1459:2cde%22','fe80::d528:99fb:d572:e289%12', '192.168.56.1', '192.168.1.2']
di desktop Windows.Ini akan berfungsi pada sebagian besar kotak linux:
sumber
Jawaban ini adalah upaya pribadi saya untuk memecahkan masalah mendapatkan IP LAN, karena
socket.gethostbyname(socket.gethostname())
juga mengembalikan 127.0.0.1. Metode ini tidak memerlukan Internet hanya koneksi LAN. Kode untuk Python 3.x tetapi dapat dengan mudah dikonversi untuk 2.x. Menggunakan Siaran UDP:sumber
127.0.1.1
adalah alamat IP asli Anda. Secara umum, komputer dapat memiliki sejumlah alamat IP. Anda dapat memfilternya untuk jaringan pribadi - 127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12 dan 192.168.0.0/16.Namun, tidak ada cara lintas platform untuk mendapatkan semua alamat IP. Di Linux, Anda dapat menggunakan
SIOCGIFCONF
ioctl.sumber
Perbaikan versi perintah yang menggunakan perintah IP, dan mengembalikan alamat IPv4 dan IPv6:
sumber
Anda dapat menggunakan perintah "ip route" di GNU / Linux untuk mengetahui alamat IP Anda saat ini.
Ini menunjukkan IP yang diberikan ke antarmuka oleh server DHCP yang berjalan pada router / modem. Biasanya "192.168.1.1/24" adalah IP untuk jaringan lokal di mana "24" berarti kisaran alamat IP posible yang diberikan oleh server DHCP dalam kisaran mask.
Berikut ini sebuah contoh: Perhatikan bahwa PyNotify hanyalah tambahan untuk menjelaskan maksud saya dan tidak diperlukan sama sekali
Keuntungannya adalah Anda tidak perlu menentukan antarmuka jaringan. Itu cukup berguna saat menjalankan server soket
Anda dapat menginstal PyNotify menggunakan easy_install atau bahkan Pip:
atau
atau dalam skrip / penerjemah python
sumber
Jika Anda mencari alamat IPV4 yang berbeda dari alamat IP localhost Anda
127.0.0.1
, berikut adalah potongan kode python yang rapi:Yang juga dapat ditulis dalam satu baris:
Bahkan jika Anda menempatkan
localhost
di/etc/hostname
, kode masih akan memberikan alamat IP lokal Anda.sumber
Untuk linux, Anda hanya dapat menggunakan
check_output
satuhostname -I
perintah sistem seperti:sumber
Catatan: Ini tidak menggunakan perpustakaan standar, tetapi cukup sederhana.
$ pip pasang pif
sumber
netifaces tersedia melalui pip dan easy_install. (Saya tahu, itu tidak ada di pangkalan, tetapi ini mungkin layak untuk dipasang.)
netifaces memang memiliki beberapa keanehan di seluruh platform:
Berikut beberapa kode netifaces untuk dimainkan:
Kode di atas tidak memetakan alamat kembali ke nama antarmuka (berguna untuk menghasilkan aturan ebtables / iptables dengan cepat). Jadi, inilah versi yang menyimpan informasi di atas dengan nama antarmuka dalam sebuah tuple:
Dan, tidak, saya tidak jatuh cinta dengan pemahaman daftar. Hanya cara otak saya bekerja hari ini.
Cuplikan berikut akan mencetak semuanya:
Nikmati!
sumber
Versi Python 3.4 menggunakan paket asyncio yang baru diperkenalkan.
Ini didasarkan pada jawaban UnkwnTech yang luar biasa .
sumber
Untuk mendapatkan alamat ip, Anda dapat menggunakan perintah shell secara langsung dengan python :
sumber