पायथन के stdlib का उपयोग करके स्थानीय IP पते खोजना


545

मैं पायथन प्लेटफ़ॉर्म में स्वतंत्र रूप से और केवल मानक पुस्तकालय का उपयोग करके स्थानीय आईपी पते (यानी 192.168.xx या 10.0.xx) कैसे पा सकता हूं?


7
स्थानीय आईपी? या सार्वजनिक आईपी? आप कई आईपी के साथ सिस्टम से कैसे निपटेंगे?
सरगुन ढिल्लन

उपयोग करें ifconfig -aऔर वहां से आउटपुट का उपयोग करें ...
फ्रेड्रिक पिहल

16
@ फ़्रेड्रिक यह एक बुरा विचार है। सबसे पहले, आप अनावश्यक रूप से एक नई प्रक्रिया के लिए धन्यवाद कर रहे हैं, और यह आपके प्रोग्राम को कसकर बंद कॉन्फ़िगरेशन में काम करने से रोक सकता है (या, आपको उन अधिकारों की अनुमति देनी होगी जिन्हें आपके प्रोग्राम की आवश्यकता नहीं है)। दूसरे, आप विभिन्न स्थानों के उपयोगकर्ताओं के लिए बग पेश करेंगे। तीसरा, यदि आप एक नया कार्यक्रम शुरू करने का निर्णय लेते हैं , तो आपको एक पदावनत शुरू नहीं करना चाहिए - ip addrकहीं अधिक उपयुक्त है (और बूट करने के लिए पार्स करना आसान है)।
१३:२० बजे फिगह

12
@ शिफा तुम बिल्कुल सही हो, मेरी मूर्खता को सही करने के लिए धन्यवाद
फ्रेड्रिक पीहल

1
यहाँ एक और मूलभूत समस्या यह है कि एक ठीक से लिखे गए आधुनिक नेटवर्किंग प्रोग्राम में स्थानीय IP पता (एस) का अधिकार (सेट) सहकर्मी या संभावित साथियों के सेट पर निर्भर करता है। यदि bindकिसी विशेष इंटरफ़ेस में सॉकेट के लिए स्थानीय आईपी पते की आवश्यकता होती है , तो यह एक नीतिगत मामला है। यदि स्थानीय आईपी पते को एक सहकर्मी को सौंपने की आवश्यकता होती है, ताकि सहकर्मी "वापस कॉल करें", यानी स्थानीय मशीन पर वापस कनेक्शन खोलने के लिए, तो स्थिति इस बात पर निर्भर करती है कि क्या कोई नेट (नेटवर्क पता अनुवाद) है बीच में बक्से। यदि कोई NAT नहीं हैं, getsocknameतो एक अच्छा विकल्प है।
पेक्का निकेंडर

जवाबों:


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

यह हमेशा काम नहीं करेगा ( 127.0.0.1होस्टनाम के /etc/hostsरूप में मशीनों पर रिटर्न 127.0.0.1), एक उपशामक वही होगा जो गिमल दिखाता है, socket.getfqdn()इसके बजाय उपयोग करें । बेशक आपकी मशीन को एक रिजॉल्व होस्टनाम की आवश्यकता है।


43
एक ध्यान दें कि यह एक मंच स्वतंत्र समाधान नहीं है। इस पद्धति का उपयोग करके बहुत सारे लिनक्स आपके आईपी पते के रूप में 127.0.0.1 लौटाएंगे।
जेसन बेकर

20
एक भिन्नता: socket.gethostbyname (socket.getfqdn ())
gimel

55
यह केवल एक आईपी पते को वापस करने के लिए प्रकट होता है। क्या होगा यदि मशीन में कई पते हों?
जेसन आर। कोमब्स

26
उबंटू पर यह किसी कारण से 127.0.1.1 रिटर्न देता है।
slikts

13
@ जैसन आर। कोम्ब्स, आईपीवी 4 पतों की सूची प्राप्त करने के लिए निम्नलिखित कोड का उपयोग करते हैं जो मेजबान मशीन के हैं:socket.gethostbyname_ex(socket.gethostname())[-1]
बरमेली

459

मैं अभी यह पाया है, लेकिन यह एक बिट hackish लगता है, हालांकि वे कहते हैं कि यह * nix पर कोशिश की और मैं खिड़कियों पर किया और यह काम किया।

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

यह मानता है कि आपके पास एक इंटरनेट एक्सेस है, और यह कि कोई स्थानीय प्रॉक्सी नहीं है।


31
अच्छा है अगर आपके पास मशीन पर कई इंटरफेस हैं, और gmail.com जैसे जो मार्गों की जरूरत है
elzapp

4
यह socket.error अपवादों को पकड़ने के लिए एक अच्छा विचार हो सकता है जो s.connect () द्वारा बढ़ सकता है!
फोबी

39
एक डोमेन नाम के बजाय आईपी पते का उपयोग करना बेहतर होगा - यह डीएनएस उपलब्धता से तेज और स्वतंत्र होना चाहिए। उदाहरण के लिए, हम 8.8.8.8 IP - Google के सार्वजनिक DNS सर्वर का उपयोग कर सकते हैं।
वॉबमेन

10
बहुत चालाक, पूरी तरह से काम करता है। जीमेल या 8.8.8.8 के बजाय, आप उस सर्वर के आईपी या पते का भी उपयोग कर सकते हैं जिसे आप देखना चाहते हैं, यदि यह लागू है।
प्रो। फॉकन कॉन्ट्रैक्ट ने 8

3
यह उदाहरण वास्तव में gmail.com को हल करने में सक्षम होने की एक बाहरी निर्भरता है। यदि आप इसे एक आईपी पते पर सेट करते हैं जो आपके स्थानीय लेन पर नहीं है (इससे कोई फर्क नहीं पड़ता कि यह ऊपर या नीचे है) तो यह निर्भरता के बिना और नेटवर्क ट्रैफ़िक के बिना काम करेगा।
गंभीर

253

यह विधि स्थानीय बॉक्स पर "प्राथमिक" आईपी (डिफ़ॉल्ट मार्ग के साथ एक) लौटाती है

  • नियमित नेट एक्सेस या किसी भी कनेक्शन की आवश्यकता नहीं है।
  • यहां तक ​​कि काम करता है अगर सभी इंटरफेस नेटवर्क से अनप्लग हैं।
  • जरूरत नहीं है या यहां तक ​​कि कहीं और पाने की कोशिश करें ।
  • NAT, सार्वजनिक, निजी, बाहरी और आंतरिक IP के साथ काम करता है
  • शुद्ध पायथन 2 (या 3) जिसमें कोई बाहरी निर्भरता नहीं है।
  • लिनक्स, विंडोज और OSX पर काम करता है।

अजगर 3 या 2:

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 Exception:
        IP = '127.0.0.1'
    finally:
        s.close()
    return IP

यह एकल IP लौटाता है जो प्राथमिक (डिफ़ॉल्ट मार्ग वाला) है। यदि आपको इसके बजाय सभी आईपी से जुड़े सभी इंटरफेस (लोकलहोस्ट, आदि सहित) की आवश्यकता है, तो यह उत्तर देखें ।

यदि आप घर पर अपने वाईफाई बॉक्स की तरह एक नैट फ़ायरवॉल के पीछे हैं, तो यह आपके सार्वजनिक NAT आईपी को नहीं दिखाएगा, बल्कि आपके निजी आईपी को स्थानीय नेटवर्क पर जो आपके स्थानीय वाईफ़ाई राउटर के लिए एक डिफ़ॉल्ट मार्ग है; आपके वाईफाई राउटर के बाहरी IP प्राप्त करने के लिए या तो इसे THAT बॉक्स पर चलाने की आवश्यकता होगी, या whatismyip.com/whatismyipaddress.com जैसी बाहरी सेवा से जुड़ना होगा जो IP को वापस दिखा सके ... लेकिन यह मूल प्रश्न से पूरी तरह अलग है। :)


7
अजगर 2 और 3 के साथ रास्पियन में काम करता है!
पियर्स.जॉसन

3
प्रतिभाशाली। VM7 सहित Win7,8,8.1 + लिनक्स टकसाल और आर्क पर काम करता है।
शर्मीली

2
विंडोज 10 प्रो में काम करता है! थैंक यू, जैमिसन बेकर!
14

3
किसी कारण से यह Mac OS X El Capitan 10.11.6 पर काम नहीं करता है (यह अपवाद OS त्रुटि उत्पन्न करता है: [Errno 49] अनुरोधित पता निर्दिष्ट नहीं कर सकता)। पोर्ट को '0' से '1' में बदलना: s.connect (('10.255.255.255 ', 1)) ने मैक ओएस एक्स और लिनक्स उबंटू 17.04
पेड्रो स्कार्पिचिया जूनियर

9
यह स्वीकृत उत्तर होना चाहिए। socket.gethostbyname(socket.gethostname())भयानक परिणाम देता है।
जेसन फ्लॉयड

142

एक उपनाम के रूप में कहा जाता है myip, कि हर जगह काम करना चाहिए:

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])'"
  • वर्तमान IPv4 पता खोजने के लिए Python 2.x, Python 3.x, आधुनिक और पुराने लिनक्स डिस्ट्रोस, OSX / macOS और विंडोज के साथ सही ढंग से काम करता है।
  • कई IP पते, IPv6, कोई कॉन्फ़िगर किया हुआ IP पता या कोई इंटरनेट एक्सेस वाली मशीनों के लिए सही परिणाम नहीं लौटाएगा।

ऊपर के समान, लेकिन केवल पायथन कोड:

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])
  • यदि कोई IP पता कॉन्फ़िगर नहीं किया गया है तो यह एक अपवाद को फेंक देगा।

वह संस्करण जो बिना इंटरनेट कनेक्शन के LAN पर भी काम करेगा:

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

( साभार @ccpizza )


पृष्ठभूमि :

उपयोग करना socket.gethostbyname(socket.gethostname())यहाँ काम नहीं आया, क्योंकि मैं जिन कंप्यूटरों पर था उनमें से एक /etc/hostsमें डुप्लिकेट प्रविष्टियों और स्वयं के संदर्भ थे। socket.gethostbyname()केवल अंतिम प्रविष्टि देता है /etc/hosts

यह मेरा प्रारंभिक प्रयास था, जो सभी पतों को शुरू करने के साथ मातम करता है "127.":

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

यह लिनक्स और विंडोज पर पायथन 2 और 3 के साथ काम करता है, लेकिन कई नेटवर्क उपकरणों या आईपीवी 6 के साथ काम नहीं करता है। हालांकि, हाल ही में लिनक्स डिस्ट्रोस पर काम करना बंद कर दिया, इसलिए मैंने इसके बजाय इस वैकल्पिक तकनीक की कोशिश की। यह 8.8.8.8पोर्ट पर Google DNS सर्वर से जुड़ने की कोशिश करता है 53:

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

फिर मैंने दो उपर्युक्त तकनीकों को एक-लाइनर में जोड़ दिया, जो हर जगह काम करना चाहिए, और myipइस उत्तर के शीर्ष पर उपनाम और पायथन स्निपेट बनाया ।

IPv6 की बढ़ती लोकप्रियता के साथ, और कई नेटवर्क इंटरफेस वाले सर्वरों के लिए, आईपी पते को खोजने के लिए एक तीसरे पक्ष के पायथन मॉड्यूल का उपयोग करना संभवतः यहां सूचीबद्ध किसी भी तरीके से अधिक मजबूत और विश्वसनीय है।


2
@ अलेक्जेंडर: सिर्फ यह कहते हुए कि यह उत्तर बहुत कम उपयोगी है जितना कि यह हुआ करता था (और ऐसा नहीं है कि डुप्लिकेट को फ़िल्टर करना एक बड़ी बात है;)। प्रलेखन के अनुसार socket.getaddrinfo()प्लेटफ़ॉर्म पर लगातार काम करना चाहिए - लेकिन मैंने इसे केवल लिनक्स पर जांचा, किसी अन्य ऑपरेटिंग सिस्टम के बारे में परेशान नहीं किया।
व्लादिमीर पलंत

1
@Alexander, /etc/resolve.conf: No such file or directoryऔर मेरे पास स्थानीय IPv4 पता है जो दिखाया गया है ifconfig
अनातोली टेकटोनिक

2
मैं पुष्टि कर सकता हूं कि अपडेट किया गया संस्करण Ubuntu 14.04 के साथ Python2 और Py3k दोनों के साथ काम करता है।
उली कोहलर

4
"अपडेट" एक यूडीपी सॉकेट पर कनेक्ट () के साथ एक अच्छी चाल दिखाता है। यह कोई ट्रैफ़िक नहीं भेजता है लेकिन आपको यह बताता है कि निर्दिष्ट प्राप्तकर्ता को पैकेट के लिए प्रेषक का पता क्या होगा। पोर्ट संभावना अप्रासंगिक है (0 भी काम करना चाहिए)। एक मल्टीहोम होस्ट पर सही सबनेट में एक पता चुनना महत्वपूर्ण है।
पीटर हैनसेन

16
सिर्फ इसलिए कि आप एक ही लाइन पर उस कोड को लिख सकते हैं, इसका मतलब यह नहीं है कि आपको ...
जैकलेओ

91

आप netifaces मॉड्यूल का उपयोग कर सकते हैं । बस टाइप करो:

pip install netifaces

आपके कमांड शेल में और यह स्वयं को डिफ़ॉल्ट पायथन इंस्टॉलेशन पर स्थापित करेगा।

तो आप इसे इस तरह से उपयोग कर सकते हैं:

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

मेरे कंप्यूटर पर यह छपा:

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

इस मॉड्यूल के लेखक का दावा है कि इसे विंडोज, यूनिक्स और मैक ओएस एक्स पर काम करना चाहिए।


20
जैसा कि प्रश्न में कहा गया है कि मुझे डिफ़ॉल्ट इंस्टॉल से कुछ चाहिए, जैसा कि किसी अतिरिक्त इंस्टॉल की आवश्यकता नहीं है।
UnkwnTech 12

4
यह मेरा पसंदीदा उत्तर होगा, सिवाय इसके कि netifaces विंडोज पर IPv6 का समर्थन नहीं करता है और अस्वस्थ दिखाई देता है। क्या किसी को पता चला है कि विंडोज पर आईपीवी 6 पते कैसे प्राप्त करें?
जीन-पॉल काल्डेरोन

3
netifaces py3k का समर्थन नहीं करता है, और उसे C कंपाइलर की आवश्यकता होती है जो कि विंडोज़ पर PITA है।
मैट जॉइनर

4
@MattJoiner इस बात के किसी भी अधिक सच है (नवीनतम संस्करण PyPI पर विंडोज बायनेरिज़ है और Py3K का समर्थन करता है)।
एलेस्टेयर

4
@ जीन-पॉलकेडरोन एफडब्ल्यूआईडब्ल्यू, नेटिफ़स का नवीनतम संस्करण विंडोज पर आईपीवी 6 का समर्थन करता है
एलेस्टेयर

47

सॉकेट एपीआई विधि

देख https://stackoverflow.com/a/28950776/711085

downsides:

  • क्रॉस-प्लेटफ़ॉर्म नहीं।
  • इंटरनेट पर विशेष पतों के अस्तित्व के लिए बंधे हुए और अधिक फ़ॉलबैक कोड की आवश्यकता होती है
  • यदि आप NAT के पीछे हैं तो यह भी काम नहीं करेगा
  • संभवतः एक यूडीपी कनेक्शन बनाता है, स्वतंत्र नहीं है (आमतौर पर आईएसपी की) डीएनएस उपलब्धता (विचारों के लिए अन्य उत्तर देखें। 8.8.8.8: गूगल का (संयोग से डीएनएस) सर्वर का उपयोग करना)
  • सुनिश्चित करें कि आप गंतव्य पते को अपरिवर्तनीय बनाते हैं, एक संख्यात्मक आईपी पते की तरह जो अप्रयुक्त होने की गारंटी है। कुछ डोमेन जैसे fakesubdomain.google.com या somefakewebsite.com का उपयोग न करें; आप अभी भी उस पार्टी (अब या भविष्य में) को स्पैमिंग करेंगे, और इस प्रक्रिया में अपने स्वयं के नेटवर्क बक्से को स्पैमिंग करेंगे।

प्रतिक्षेपक विधि

(ध्यान दें कि यह ओपी के स्थानीय आईपी पते के प्रश्न का उत्तर नहीं देता है, जैसे कि 192.168 ..., यह आपको आपका सार्वजनिक आईपी पता देता है, जो उपयोग के मामले के आधार पर अधिक वांछनीय हो सकता है।)

आप कुछ साइट जैसे whatismyip.com (लेकिन एक एपीआई के साथ) को क्वेरी कर सकते हैं, जैसे:

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)

या अगर 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)

लाभ:

  • इस पद्धति का एक पहलू यह क्रॉस-प्लेटफ़ॉर्म है
  • यह बदसूरत NATs (उदाहरण के लिए आपके घर का राउटर) के पीछे से काम करता है।

नुकसान (और workarounds):

  • इस वेबसाइट को बनाने की आवश्यकता है, बदलने के लिए प्रारूप (लगभग निश्चित रूप से नहीं होगा), और आपके डीएनएस सर्वर काम करने के लिए। एक विफलता के मामले में अन्य तीसरे पक्ष के आईपी एड्रेस रिफ्लेक्टर को भी क्वेरी करके इस समस्या को कम कर सकता है।
  • संभावित आक्रमण वेक्टर यदि आप कई रिफ्लेक्टर को क्वेरी नहीं करते हैं (एक परावर्तित परावर्तक को यह बताने से रोकने के लिए कि आपका पता कुछ ऐसा है), या यदि आप HTTPS का उपयोग नहीं करते हैं (एक आदमी के बीच के हमले को रोकने के लिए नाटक कर रहे हैं सर्वर होना)

संपादित करें : हालांकि शुरू में मुझे लगा कि ये तरीके वास्तव में बुरे थे (जब तक कि आप कई कमियों का उपयोग नहीं करते हैं, कोड अब से कई साल बाद अप्रासंगिक हो सकता है), यह प्रश्न "इंटरनेट क्या है?" एक कंप्यूटर में कई अलग-अलग नेटवर्क को इंगित करने वाले कई इंटरफेस हो सकते हैं। विषय के अधिक गहन विवरण के लिए, Google के लिएgateways and routes । एक कंप्यूटर एक आंतरिक नेटवर्क को आंतरिक गेटवे के माध्यम से एक्सेस करने में सक्षम हो सकता है, या एक राउटर के माध्यम से विश्व-व्यापी वेब तक पहुंच सकता है उदाहरण के लिए एक राउटर (आमतौर पर मामला)। स्थानीय IP पता, जो ओपी के बारे में पूछता है, केवल एकल लिंक परत के संबंध में अच्छी तरह से परिभाषित है, इसलिए आपको यह निर्दिष्ट करना होगा कि ("क्या यह नेटवर्क कार्ड है, या ईथरनेट केबल, जिसके बारे में हम बात कर रहे हैं?") । इस प्रश्न के कई गैर-अनूठे उत्तर हो सकते हैं जैसे कि समक्ष रखी गई हो। हालांकि विश्वव्यापी वेब पर वैश्विक आईपी पता शायद अच्छी तरह से परिभाषित है (बड़े पैमाने पर नेटवर्क विखंडन की अनुपस्थिति में): शायद गेटवे के माध्यम से वापसी का रास्ता जो टीएलडी तक पहुंच सकता है।


यदि आप NAT के पीछे हैं, तो यह आपका LAN-चौड़ा पता वापस कर देगा। यदि आप इंटरनेट से जुड़ रहे हैं, तो आप एक वेब सेवा से जुड़ सकते हैं, जो आपके सार्वजनिक आईपी पते में से एक को लौटाती है।
फ़िहग

यह TCP कनेक्शन नहीं बनाता है क्योंकि यह UDP कनेक्शन बनाता है।
अनुज गुप्ता

2
सॉकेट एपीआई संस्करण में एक विकल्प के रूप में, s.setsockopt (socket.SOL_SOCKET, socket.S_BROADCAST, 1) के साथ s.connect (('INSERT SOME TARGET WEBSITE.com', 0) को बदलें; s.connect ('<> प्रसारण> ', 0)) DNS लुकअप से बचने के लिए। (मुझे लगता है कि अगर कोई फ़ायरवॉल है तो प्रसारण के साथ कोई समस्या हो सकती है)
dlm

45

यदि कंप्यूटर में इंटरनेट का मार्ग है, तो यह हमेशा पसंदीदा स्थानीय आईपी पते को प्राप्त करने के लिए काम करेगा , भले ही / आदि / मेजबानों को सही ढंग से सेट न किया गया हो।

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]

यह कैसे काम करता है ? , 8.8.8.8एक google dns सर्वर है जो हम स्थानीय dns सर्वर के साथ कर सकते हैं?
Ciasto पाईकरज़

39

लिनक्स पर:

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

तो यह प्रभावी रूप से एक सॉकेट खोलता है जो इसके साथ कुछ नहीं करता है और आप स्थानीय आईपी प्राप्त करने के लिए उस सॉकेट के बारे में कच्चे डेटा की जांच करते हैं?
डेव

1
सॉकेट को कर्नेल के माध्यम से संचार करने के लिए एक fd प्राप्त करने के लिए खोला जाता है (के माध्यम से ioctl)। सॉकेट उस इंटरफ़ेस को बाध्य नहीं करता है जिसके लिए आप Addr के बारे में जानकारी चाहते हैं- इसके उपयोगकर्ता और कर्नेल के बीच संचार तंत्र। en.wikipedia.org/wiki/Ioctl lxr.free-electrons.com/source/net/socket.c
tMC

2
Python3 पर एक संशोधन के साथ काम करता है: struct.pack('16sH14s', iface, socket.AF_INET, '\x00'*14)को प्रतिस्थापित किया जाना चाहिएstruct.pack('16sH14s', iface.encode('utf-8'), socket.AF_INET, b'\x00'*14)
pepoluan

1
@ChristianFischer ioctlएक विरासत इंटरफ़ेस है, मेरा मानना ​​है कि IPv6 का समर्थन नहीं करता है और संभवतः कभी नहीं होगा। मुझे लगता है कि 'राइट' तरीका नेटलिंक के माध्यम से है जो पायथन में बहुत सीधा नहीं है। मुझे लगता है कि libc में फ़ंक्शन होना चाहिए जो कि getifaddrsअजगर ctypesमॉड्यूल के माध्यम से पहुँचा जा सकता है जो काम कर सकता है - man7.org/linux/man-pages/man3/getifaddrs.3.html
tMC

1
@ मैडी ioctl एक विरासत इंटरफ़ेस है, मेरा मानना ​​है कि IPv6 का समर्थन नहीं करता है और कभी नहीं होगा। मुझे लगता है कि 'राइट' तरीका नेटलिंक के माध्यम से है जो पायथन में बहुत सीधा नहीं है। मुझे लगता है कि libc में फ़ंक्शन गेटिफ़ैडर्स होना चाहिए जो कि अजगर ctypes मॉड्यूल के माध्यम से पहुँचा जा सकता है जो काम कर सकता है - man7.org/linux/man-pages/man3/getifaddrs.3.html
tMC2

27

निम्नलिखित मॉड्यूल का उपयोग कर im:

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

विंडोज़ और लिनक्स के साथ परीक्षण किया गया है (और उन के लिए अतिरिक्त मॉड्यूल की आवश्यकता नहीं है) उन प्रणालियों पर उपयोग के लिए है जो एक एकल आईपीवी 4 आधारित लैन में हैं।

इंटरफ़ेस नामों की निश्चित सूची हाल के लिनक्स संस्करणों के लिए काम नहीं करती है, जिन्होंने सिकंदर द्वारा इंगित किए गए पूर्वानुमानित इंटरफ़ेस नामों के बारे में सिस्टम v197 परिवर्तन को अपनाया है । ऐसे मामलों में, आपको अपने सिस्टम पर इंटरफ़ेस नामों के साथ सूची को मैन्युअल रूप से प्रतिस्थापित करने की आवश्यकता है, या नेटिफ़ास जैसे किसी अन्य समाधान का उपयोग करें ।


2
यह नए पूर्वानुमानित लिनक्स इंटरफ़ेस नामों के साथ असंगत है, जैसे कि enp0s25। अधिक जानकारी के लिए, wiki.archlinux.org/index.php/Network_Configuration#Device_names
Alexander

2
मैं अजगर 3.4 का उपयोग कर रहा था और 'struct.pack (...)' भाग को 'struct.pack (' 256s ', बाइट्स (ifname [: 15],' utf-8 ')) में बदलने की जरूरत थी। इस प्रश्न को देखें: stackoverflow.com/q/27391167/76010
Bakanekobrain

1
रसियनियन डब्ल्यू / पायथन 2.7.3 पर - बाइट्स () को 2 तर्क पसंद नहीं आया। लेकिन इसने काम किया: struct.pack('256s', bytes(ifname[:15]))
colm.anseo

24

मैं अपने ubuntu मशीनों पर इस का उपयोग करें:

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

यह काम नहीं करता है।


अच्छा और सरल। अमेज़ॅन के लिनक्स एएमआई पर भी काम करता है, लेकिन केवल अगर मैं रूट हूं। अन्यथा मुझे एक त्रुटि मिलेगी: 'श: ifconfig: कमांड नहीं मिली'
इगोरगानापोलस्की

तो आप का उपयोग करना चाहिए "/ sbin / ifconfig" की तरह gavaletz ने कहा। यह Red Hat 4.1.2-48 पर भी काम करता है।
इगोरगानापोलस्की 17

7
2.6 के बाद से पदावनत। कमांड चलाने के लिए सबप्रोसेस मॉड्यूल का उपयोग करें ।
कॉलिन डंकलाउ

5
और ifconfig के रूप में अच्छी तरह से पदावनत है। Iproute2 का उपयोग करें।
हेल्मुट ग्रोने

सभी ips प्राप्त करें: आयात श; [ip.split () [१] [५:] फिल्टर में आईपी के लिए (लैम्ब्डा x: et inet addr ’in x, sh.ifconfig ()। स्प्लिट (" \ n ")]
गेब्रियल लैंसमैन

20

यदि आप बाहरी पैकेज का उपयोग नहीं करना चाहते हैं और बाहर के इंटरनेट सर्वर पर भरोसा नहीं करना चाहते हैं, तो इससे मदद मिल सकती है। यह एक कोड नमूना है जो मुझे Google कोड खोज पर मिला है और आवश्यक जानकारी वापस करने के लिए संशोधित किया गया है:

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

उपयोग:

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

जैसा कि यह निर्भर करता है windll, यह केवल विंडोज पर काम करेगा।


ऊपर एक लाइनर समाधान आम तौर पर खिड़कियों पर काम करता है। यह लिनक्स एक समस्या है।
रिक्री

14
+1 यह तकनीक कम से कम मशीन के सभी पतों को वापस करने का प्रयास करती है।
जेसन आर। कोम्बस

1
यह स्क्रिप्ट पहले पते पर लौटने के बाद मेरी मशीन पर विफल हो जाती है। त्रुटि "विशेषता है: 'LP_IP_ADDR_STRING' ऑब्जेक्ट में कोई विशेषता नहीं है 'ipAddress'" मुझे संदेह है कि इसका IPv6 पते के साथ कुछ करना है।
जेसन आर

1
यह पता चला है कि कुछ भी है, लेकिन पहले आईपी पते के लिए, एडनोड को संदर्भित नहीं किया गया है। उदाहरण के लिए लूप में एक और रेखा जोड़ें और यह मेरे लिए काम करता है: adNode = adNode.contents
जेसन आर। कोम्ब्स

18

डेबियन (परीक्षण) पर और मुझे सबसे अधिक लिनक्स पर शक है ।।

import commands

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

एमएस विंडोज पर (परीक्षण)

import socket

socket.gethostbyname(socket.gethostname())

1
MacOS पर काम नहीं करता है:hostname: illegal option -- I\nusage: hostname [-fs] [name-of-host]
डेरेक 會 功夫

18

एक संस्करण मुझे विश्वास नहीं है कि अभी तक पोस्ट किया गया है। मैंने Ubuntu 12.04 पर अजगर 2.7 के साथ परीक्षण किया।

इस समाधान को यहां देखें: 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])

उदाहरण परिणाम:

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

2
पायथन 3, उबंटू 18.04 पर काम करता है; स्ट्रिंग को बाइट्स की आवश्यकता है: >>> socket.inet_ntoa (fcntl.ioctl (s.fileno), 0x8915, struct.pack ('256s', 'enp0s31x6']: 15] .encode ('utf-8')। )) [२०:२४]) 2 १
२.१६'.१.१

12

Ninjagecko के उत्तर पर भिन्नता। यह किसी भी लैन पर काम करना चाहिए जो यूडीपी को प्रसारित करने की अनुमति देता है और लैन या इंटरनेट पर एक पते तक पहुंचने की आवश्यकता नहीं है।

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

रुको, <broadcast>एक मान्य होस्टनाम कैसे है ? !! इस प्रकार के कितने मौखिक होस्टनाम मान्य हैं?
देव अग्रवाल

यह मेरे लिए Ubuntu 20.04 पर काम करता है - 192.168.0.24 नहीं 127.0.0.1
लुईस मॉरिस

8

मुझे डर है कि किसी अन्य कंप्यूटर से जुड़ने और इसे अपना आईपी पता भेजने के अलावा कोई अच्छा प्लेटफ़ॉर्म स्वतंत्र तरीका नहीं है। उदाहरण के लिए: findmyipaddress । ध्यान दें कि यह काम नहीं करेगा यदि आपको NAT के पीछे एक IP पते की आवश्यकता है जब तक कि आप जो कंप्यूटर कनेक्ट कर रहे हैं वह NAT के पीछे भी है।

यहां एक समाधान है जो लिनक्स में काम करता है: एक नेटवर्क इंटरफ़ेस से जुड़ा आईपी पता प्राप्त करें


8

कमांड लाइन के बर्तनों के माध्यम से "स्वच्छ" उत्पादन का एक सरल तरीका:

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

यह सिस्टम पर सभी IPv4 पते दिखाएगा।


1
यह सभी IPv4 पते नहीं दिखाएगा, क्योंकि ifconfig केवल आपको प्राथमिक के बारे में बताता है। सभी पते देखने के लिए आपको iproute2 से "ip" का उपयोग करना होगा।
हेल्मुट ग्रोने

यह मानक पुस्तकालय के लिए पूछ रहे एक प्रश्न के लिए बहुत सारे शेल का एक नरक है ... इसके अलावा, ifconfig न तो पोर्टेबल है और एक मशीन पर भी मज़बूती से काम नहीं करेगा।
डोमिनिक जॉर्ज

7

FYI करें मैं सत्यापित कर सकता हूं कि विधि:

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

OS X (10.6,10.5), Windows XP और एक अच्छी तरह से प्रशासित RHEL विभाग सर्वर पर काम करता है। यह बहुत कम CentOS VM पर काम नहीं करता था कि मैं अभी कुछ कर्नेल हैकिंग करता हूं। तो उस उदाहरण के लिए आप सिर्फ 127.0.0.1 पते की जांच कर सकते हैं और उस स्थिति में निम्नलिखित कार्य करें:

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

और फिर आउटपुट से आईपी पते को पार्स करें। यह ध्यान दिया जाना चाहिए कि ifconfig डिफ़ॉल्ट रूप से सामान्य उपयोगकर्ता के PATH में नहीं है और यही कारण है कि मैं कमांड में पूरा पथ देता हूं। आशा है कि ये आपकी मदद करेगा।


7

यह UnkwnTech के उत्तर का एक प्रकार है - यह एक get_local_addr()फ़ंक्शन प्रदान करता है , जो होस्ट का प्राथमिक LAN आईपी पता देता है। मैं इसे पोस्ट कर रहा हूं क्योंकि यह कई चीजों को जोड़ता है: ipv6 समर्थन, त्रुटि से निपटने, लोकलहोस्ट / लिंकलोकल ऐडर्स की अनदेखी, और कनेक्ट करने के लिए एक TESTNET addr (rfc5737) का उपयोग करता है।

# imports
import errno
import socket
import logging

# 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:
        # log.info("trapped error connecting to %r via %r", remote, family, exc_info=True)
        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

मुझे लगा कि यह एक बहुत अच्छा जवाब हो सकता है .. लेकिन यह हमेशा लौटता हैNone
जेमी लिंडसे

@JamieLindsey क्या आपके पास अपने OS, नेटवर्क कॉन्फ़िगरेशन के बारे में कुछ विवरण हैं? इसके अलावा, get_local_addr(remove="www.google.com")रिटर्न की तरह क्या है ? socket.error_Get_local_addr () द्वारा थ्रो को लॉग करने से निदान में मदद मिल सकती है।
एली कॉलिन्स

6
import socket
[i[4][0] for i in socket.getaddrinfo(socket.gethostname(), None)]

1
हम्म ... दो एनआईसी के साथ एक सर्वर पर यह निर्दिष्ट आईपी पते में से एक देता है , लेकिन तीन बार दोहराया जाता है। मेरे लैपटॉप पर यह '127.0.1.1' (तीन बार दोहराया ...) ...
bryn

मुझे ['fe80::34e8:fe19:1459:2cde%22','fe80::d528:99fb:d572:e289%12', '192.168.56.1', '192.168.1.2']विंडोज डेस्कटॉप पर देता है ।
नकीलोन

5

यह अधिकांश लिनक्स बॉक्स पर काम करेगा:

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

5

यह जवाब लैन आईपी प्राप्त करने की समस्या को हल करने का मेरा व्यक्तिगत प्रयास है, क्योंकि socket.gethostbyname(socket.gethostname())यह 127.0.0.1 भी लौटा है। इस विधि के लिए इंटरनेट की जरूरत नहीं है सिर्फ एक लैन कनेक्शन। कोड पायथन 3.x के लिए है लेकिन आसानी से 2.x के लिए परिवर्तित किया जा सकता है। यूडीपी प्रसारण का उपयोग करना:

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

1
यदि आप एक साथ एक ही नेटवर्क पर दो मशीनों पर इसे चलाते हैं, तो क्या होता है? जैसा कि आप नेटवर्क पर अपना संदेश प्रसारित करते हैं, सभी मशीनों को 'मेरा लैन आईपी पता क्या है' प्राप्त होगा। आपके udp_listening_server संदेश पर 'आपका IP पता xxx है' का उत्तर दे सकता है।
निकोलस डेफ्रानौक्स

4

127.0.1.1 है अपने असली आईपी पते। अधिक सामान्य रूप से, किसी कंप्यूटर में किसी भी आईपी पते की संख्या हो सकती है। आप उन्हें निजी नेटवर्क के लिए फ़िल्टर कर सकते हैं - 127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12 और 192.168.0.0/16।

हालांकि, सभी आईपी पते प्राप्त करने के लिए कोई क्रॉस-प्लेटफ़ॉर्म तरीका नहीं है। लिनक्स पर, आप SIOCGIFCONFioctl का उपयोग कर सकते हैं ।


2
वह अपने बाहरी रूप से दिखाई देने वाले आई.पी. 127। *। *। * रेंज आमतौर पर स्थानीयहोस्ट या आंतरिक नेटवर्क को संदर्भित करता है, जो स्पष्ट रूप से वह नहीं है जो वह चाहता है।
सेरिन

4

IP संस्करण का उपयोग करने वाले कमांड संस्करण का एक मामूली शोधन, और IPv4 और 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)]

4

वैसे आप अपने वर्तमान आईपी पते को जानने के लिए GNU / Linux पर कमांड "आईपी मार्ग" का उपयोग कर सकते हैं।

यह राउटर / मॉडेम पर चलने वाले डीएचसीपी सर्वर द्वारा इंटरफेस को दिए गए आईपी को दर्शाता है। आमतौर पर "192.168.1.1/24" स्थानीय नेटवर्क के लिए आईपी है जहां "24" का अर्थ है मास्क रेंज के भीतर डीएचसीपी सर्वर द्वारा दिए गए पॉसिबल आईपी पतों की श्रेणी।

यहाँ एक उदाहरण है: ध्यान दें कि PyNotify मेरी बात को सीधे प्राप्त करने के लिए एक अतिरिक्त है और इसकी बिल्कुल आवश्यकता नहीं है

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

इसका लाभ यह है कि आपको नेटवर्क इंटरफ़ेस निर्दिष्ट करने की आवश्यकता नहीं है। सॉकेट सर्वर चलाते समय यह बहुत उपयोगी है

आप easy_install या यहां तक ​​कि Pip का उपयोग करके PyNotify स्थापित कर सकते हैं:

easy_install py-notify

या

pip install py-notify

या अजगर स्क्रिप्ट / दुभाषिया के भीतर

from pip import main

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

4

यदि आप अपने लोकलहोस्ट आईपी पते से भिन्न IPV4 पते की तलाश कर रहे हैं 127.0.0.1, तो यहां अजगर कोड का एक साफ टुकड़ा है:

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

जिसे एक पंक्ति में भी लिखा जा सकता है:

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

यहां तक ​​कि अगर आप अंदर डालते localhostहैं /etc/hostname, तो भी कोड आपके स्थानीय आईपी पते को देगा।


4

लिनक्स के लिए, आप बस सिस्टम कमांड check_outputका उपयोग कर सकते हैं hostname -Iजैसे:

from subprocess import check_output
check_output(['hostname', '-I'])

गोगलर्स के लिए, मुझे पता है कि प्रश्न एक क्रॉस प्लेटफ़ॉर्म समाधान के लिए था
कैस्पर स्केइट एंडरसन

3

नोट: यह मानक पुस्तकालय का उपयोग नहीं कर रहा है, लेकिन काफी सरल है।

$ पाईप स्थापित करें

from pif import get_public_ip
get_public_ip()

3
सवाल stdlib का उपयोग कर आईपी को खोजने के बारे में था
अलेक्जेंड्रू

3

netifaces पाइप और easy_install के माध्यम से उपलब्ध है। (मुझे पता है, यह आधार में नहीं है, लेकिन यह स्थापित करने के लायक हो सकता है।)

प्लेटफ़ॉर्म पर नेटिफ़स में कुछ विषमताएँ हैं:

  • लोकलहोस्ट / लूप-बैक इंटरफ़ेस हमेशा शामिल नहीं किया जा सकता है (सिगविन)।
  • पते प्रति-प्रोटोकॉल (उदाहरण के लिए, आईपीवी 4, आईपीवी 6) और प्रोटोकॉल प्रति-इंटरफ़ेस सूचीबद्ध हैं। कुछ प्रणालियों (लिनक्स) पर प्रत्येक प्रोटोकॉल-इंटरफ़ेस जोड़ी का अपना स्वयं का संबद्ध इंटरफ़ेस होता है (इंटरफ़ेस_नाम: एन नोटेशन का उपयोग करते हुए) जबकि अन्य सिस्टम (विंडोज) पर एक एकल इंटरफ़ेस में प्रत्येक प्रोटोकॉल के पते की एक सूची होगी। दोनों ही मामलों में एक प्रोटोकॉल सूची है, लेकिन इसमें केवल एक ही तत्व हो सकता है।

यहाँ कुछ netifaces कोड के साथ खेलने के लिए है:

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.

उपरोक्त कोड अपने इंटरफ़ेस नाम के पते पर वापस मैप नहीं करता है (मक्खी पर ईबेबलेट्स / आईपीटेबल्स नियम बनाने के लिए उपयोगी)। तो यहाँ एक संस्करण है जो एक टुपल में इंटरफ़ेस नाम के साथ उपरोक्त जानकारी रखता है:

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]

और, नहीं, मैं सूची की समझ के साथ प्यार में नहीं हूं। यह इन दिनों मेरे दिमाग के काम करने का तरीका ही है।

निम्नलिखित स्निपेट इसे प्रिंट आउट कर देगा:

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)

का आनंद लें!


इस मुद्दे से निपटने के दौरान नेटिफ़ेस वास्तव में जीवन को बहुत आसान बना देता है।
ड्रेक गुआन

3

नए पेश किए गए एसिंसीओ पैकेज का उपयोग करते हुए पायथन 3.4 संस्करण।

async get_local_ip():
    loop = asyncio.get_event_loop()
    transport, protocol = await loop.create_datagram_endpoint(
        asyncio.DatagramProtocol,
        remote_addr=('8.8.8.8', 80))
    result = transport.get_extra_info('sockname')[0])
    transport.close()
    return result

यह UnkwnTech के उत्कृष्ट उत्तर पर आधारित है ।


3

आईपी ​​पते को प्राप्त करने के लिए आप सीधे एक शेल कमांड का उपयोग अजगर में कर सकते हैं :

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()
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.