পাইথনের stdlib ব্যবহার করে স্থানীয় আইপি ঠিকানাগুলি সন্ধান করা


545

পাইথন প্ল্যাটফর্মে স্বতন্ত্রভাবে এবং কেবলমাত্র স্ট্যান্ডার্ড লাইব্রেরি ব্যবহার করে আমি কীভাবে স্থানীয় আইপি ঠিকানাগুলি (যেমন 192.168.xx বা 10.0.xx) খুঁজে পেতে পারি?


7
লোকাল আইপি? নাকি পাবলিক আইপি? আপনি একাধিক আইপি সহ সিস্টেমগুলি কীভাবে কাজ করবেন?
সরগুন illিলন

ifconfig -aসেখান থেকে আউটপুটটি ব্যবহার করুন এবং ব্যবহার করুন ...
ফ্রেডরিক পিহল

16
@ ফ্রেড্রিক এটি খারাপ ধারণা। প্রথমত, আপনি অযাচিতভাবে একটি নতুন প্রক্রিয়া তৈরি করছেন, এবং এটি আপনার প্রোগ্রামটিকে শক্তভাবে লক করা কনফিগারেশনে কাজ করা থেকে বাধা দিতে পারে (বা, আপনার প্রোগ্রামটির প্রয়োজন নেই এমন অধিকারগুলি আপনাকে মঞ্জুর করতে হবে)। দ্বিতীয়ত, আপনি বিভিন্ন লোকেলের ব্যবহারকারীদের জন্য বাগগুলি প্রবর্তন করবেন। তৃতীয়ত, আপনি যদি কোনও নতুন প্রোগ্রাম শুরু করার সিদ্ধান্ত নেন তবে আপনার হতাশ একটিটি শুরু করা উচিত নয় - ip addrএটি আরও বেশি উপযুক্ত (এবং পার্স করা সহজ, বুট করা সহজ)।
ফিহাগ

12
@ ফিহাগ আপনি একেবারে সঠিক, আমার বোকামি সংশোধন করার জন্য ধন্যবাদ
ফ্রেডরিক পিহল

1
এখানে আরও একটি মৌলিক সমস্যা হ'ল সঠিকভাবে লিখিত আধুনিক নেটওয়ার্কিং প্রোগ্রামে ডান (সেট) স্থানীয় আইপি অ্যাড্রেস (এস) পিয়ার, বা সম্ভাব্য পিয়ারের সেটের উপর নির্ভর করে। 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 এ ফিরে আসবে।
জেসন বাকের 12

20
একটি প্রকরণ: socket.gethostbyname (socket.getfqdn ())
জিমেল

55
এটি কেবলমাত্র একটি একক আইপি ঠিকানা ফেরত দেবে বলে মনে হচ্ছে। মেশিনের একাধিক ঠিকানা থাকলে কী হবে?
জেসন আর। কুমবস

26
উবুন্টুতে এটি কোনও কারণে 127.0.1.1 প্রদান করে।
20:55

13
@ জেসন আর। কোমবস, হোস্ট মেশিনের অন্তর্ভুক্ত আইপিভি 4 ঠিকানাগুলির তালিকা পুনরুদ্ধার করতে নিম্নলিখিত কোডটি ব্যবহার করুন:socket.gethostbyname_ex(socket.gethostname())[-1]
বারামেলি

459

আমি এটি খুঁজে পেয়েছি তবে এটি কিছুটা হ্যাশিশ মনে হয়, তবে তারা বলে যে এটি * নিক্সে চেষ্টা করেছিলাম এবং আমি উইন্ডোতে করেছি এবং এটি কাজ করে।

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 যেমন
এলজাপ্প

4
সকেটকে ধরা ভাল ধারণা হতে পারে!
ফোবি

39
কোনও ডোমেন নামের পরিবর্তে আইপি ঠিকানা ব্যবহার করা ভাল - এটি ডিএনএস উপলভ্যতা থেকে দ্রুত এবং স্বতন্ত্র হতে হবে। যেমন আমরা 8.8.8.8 আইপি ব্যবহার করতে পারি - গুগলের সর্বজনীন ডিএনএস সার্ভার।
wobmene

10
খুব চালাক, পুরোপুরি কাজ করে। জিমেইল বা ৮.৮.৮.৮ পরিবর্তে আপনি যে সার্ভারটি দেখতে চান সেটির আইপি বা ঠিকানা ব্যবহার করতে পারেন, যদি তা প্রযোজ্য হয়।
অধ্যাপক ফ্যালকেন চুক্তি

3
এই উদাহরণটির gmail.com প্রকৃতপক্ষে সমাধান করতে সক্ষম হওয়ার একটি বাহ্যিক নির্ভরতা রয়েছে। যদি আপনি এটিকে এমন কোনও আইপি ঠিকানায় সেট করেন যা আপনার স্থানীয় লেনে নেই (এটি উপরে বা নীচে নেমে আসে না) এটি নির্ভরতা ছাড়াই এবং নেটওয়ার্ক ট্র্যাফিক ছাড়াই কাজ করবে।
ভয়াবহ

253

এই পদ্ধতিটি স্থানীয় বাক্সে "প্রাথমিক" আইপি ফেরত দেয় (একটি ডিফল্ট রুট সহ একটি)

  • রাউটেবল নেট অ্যাক্সেস বা কোনও সংযোগের প্রয়োজন নেই।
  • সমস্ত ইন্টারফেস নেটওয়ার্ক থেকে প্লাগ লাগানো থাকলেও কাজ করে।
  • অন্য কোথাও যাওয়ার প্রয়োজন নেই এমনকি চেষ্টা করার দরকার নেই
  • NAT, পাবলিক, প্রাইভেট, বাহ্যিক এবং অভ্যন্তরীণ IP এর সাথে কাজ করে
  • খাঁটি পাইথন 2 (বা 3) কোনও বাহ্যিক নির্ভরতা ছাড়াই।
  • লিনাক্স, উইন্ডোজ এবং ওএসএক্সে কাজ করে।

পাইথন 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

এটি একটি একক আইপি প্রদান করে যা প্রাথমিক (ডিফল্ট রুট সহ একটি)। যদি আপনার পরিবর্তে সমস্ত আইপি'র সমস্ত ইন্টারফেসের সাথে সংযুক্ত (লোকালহোস্ট ইত্যাদি) দরকার হয় তবে এই উত্তরটি দেখুন

যদি আপনি বাড়িতে আপনার ওয়াইফাই বাক্সের মতো একটি NAT ফায়ারওয়ালের পিছনে থাকেন তবে এটি আপনার সর্বজনীন NAT আইপি প্রদর্শন করবে না, পরিবর্তে আপনার স্থানীয় নেটওয়ার্কে আপনার ব্যক্তিগত আইপি যা আপনার স্থানীয় WIFI রাউটারের একটি ডিফল্ট রুট রয়েছে; আপনার ওয়াইফাই রাউটারের বাহ্যিক আইপি পেতে হয় এটি এই বাক্সে চলমান হবে, বা কোনও আইসিসিআইপি / হোয়াটস্মিআইপ্যাড্রেস.কমের মতো কোনও বাহ্যিক পরিষেবাতে সংযুক্ত হওয়ার দরকার যা আইপিটি প্রতিফলিত করতে পারে ... তবে এটি মূল প্রশ্ন থেকে সম্পূর্ণ পৃথক। :)


7
পাইথন 2 এবং 3 এর সাথে রাস্পবিয়ানে কাজ করে!
pierce.jason

3
উজ্জ্বল। ভিএম 7 সহ উইন 7,8,8.1 + লিনাক্স মিন্ট এবং আর্কে কাজ করে।
শেরেমি

2
উইন্ডোজ 10 প্রোতে কাজ করে! ধন্যবাদ, জ্যামিসন বেকার!
14

3
কোনও কারণে এটি ম্যাক ওএস এক্স এল ক্যাপিটান 10.11.6 এ কাজ করে না (এটি একটি ব্যতিক্রম ওএস ত্রুটি উত্পন্ন করে: [ত্রুটি 49] অনুরোধ করা ঠিকানা বরাদ্দ করতে পারে না)। '0' থেকে '1' তে বন্দরটি পরিবর্তন করা: এস.কনেক্ট (('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])'"
  • বর্তমান আইপিভি 4 ঠিকানা সন্ধানের জন্য পাইথন 2.x, পাইথন 3.x, আধুনিক এবং পুরাতন লিনাক্স ডিস্ট্রোস, ওএসএক্স / ম্যাকোস এবং উইন্ডোজের সাথে সঠিকভাবে কাজ করে।
  • একাধিক আইপি ঠিকানা, আইপিভি,, কোনও কনফিগার করা আইপি ঠিকানা বা কোনও ইন্টারনেট অ্যাক্সেস সহ মেশিনগুলির জন্য সঠিক ফলাফলটি ফিরিয়ে দেবে না।

উপরের মত একই, তবে কেবল পাইথন কোড:

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])
  • কোনও আইপি ঠিকানা কনফিগার করা না থাকলে এটি একটি ব্যতিক্রম ছুঁড়ে দেবে।

ইন্টারনেট সংযোগ ছাড়াই ল্যানগুলিতেও কাজ করবে এমন সংস্করণ:

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

(ধন্যবাদ @ সিপিপিজ্জা )


পটভূমি :

ব্যবহার 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বন্দরে গুগল ডিএনএস সার্ভারের সাথে সংযোগ স্থাপনের চেষ্টা করে 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এবং এই উত্তরের শীর্ষে উপনাম এবং পাইথন স্নিপেট তৈরি করেছি ।

আইপিভি of-এর ক্রমবর্ধমান জনপ্রিয়তা এবং একাধিক নেটওয়ার্ক ইন্টারফেস সহ সার্ভারের জন্য, আইপি ঠিকানা সন্ধানের জন্য তৃতীয় পক্ষের পাইথন মডিউল ব্যবহার করা সম্ভবত এখানে তালিকাভুক্ত যে কোনও পদ্ধতির চেয়ে বেশি শক্তিশালী এবং নির্ভরযোগ্য।


2
@ আলেকজান্দার: কেবল এটিই বলেছিলেন যে এই উত্তরটি তার আগের তুলনায় অনেক কম দরকারী (এবং এটি নকলগুলি ছাঁটাই বড় ব্যাপার নয়))। ডকুমেন্টেশন অনুসারে socket.getaddrinfo()প্ল্যাটফর্মগুলি জুড়ে ধারাবাহিকভাবে কাজ করা উচিত - তবে আমি এটি কেবল লিনাক্সে পরীক্ষা করেছি, অন্য কোনও অপারেটিং সিস্টেম নিয়ে মাথা ঘামাইনি।
ওলাদিমির প্যালান্ট

1
@ আলেকজান্ডার, /etc/resolve.conf: No such file or directoryএবং আমার দেখানো স্থানীয় আইপিভি 4 ঠিকানা রয়েছে ifconfig
অ্যানাটোলি টেকটোনিক

2
আমি নিশ্চিত করতে পারি যে আপডেট হওয়া সংস্করণ পাইথন 2 এবং পাই 3 কে উভয়ের সাথে উবুন্টু 14.04 এর সাথে কাজ করে।
উলি কাহলারের

4
"আপডেট" একটি ইউডিপি সকেটে কানেক্ট () সহ একটি দুর্দান্ত কৌশল দেখায়। এটি কোনও ট্র্যাফিক প্রেরণ করে না তবে আপনাকে নির্দিষ্ট প্রাপকের কাছে প্যাকেটের জন্য প্রেরকের ঠিকানাটি কী তা খুঁজে পেতে দেয়। বন্দরটি সম্ভবত অপ্রাসঙ্গিক (এমনকি 0 টিও কাজ করা উচিত)। মাল্টিহোমড হোস্টে ডান সাবনেটে একটি ঠিকানা বাছাই গুরুত্বপূর্ণ।
পিটার হানসেন

16
কেবলমাত্র আপনি সেই কোডটি একটি লাইনে লিখতে পারেন, তার অর্থ এই নয় যে আপনার উচিত ...
জ্যাকলিয়ো

91

আপনি নেটিফেস মডিউলটি ব্যবহার করতে পারেন । লিখো:

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

আমার কম্পিউটারে এটি মুদ্রিত:

63 45639BDC-1050-46E0-9BE9-075C30DE1FBC 192: 192.168.0.100
{D43A468B-F3AE-4BF9-9391-4863A4500583 10: 10.5.9.207

এই মডিউলটির লেখক দাবি করেছেন এটি উইন্ডোজ, ইউএনআইএক্স এবং ম্যাক ওএস এক্সে কাজ করা উচিত should


20
প্রশ্নে বর্ণিত হিসাবে আমি ডিফল্ট ইনস্টল থেকে কিছু চাই, যেমন কোনও অতিরিক্ত ইনস্টলের প্রয়োজন নেই।
UnkwnTech

4
নেটিফেসগুলি উইন্ডোজে আইপিভি 6 সমর্থন করে না এবং এটি অনিচ্ছাকৃত প্রদর্শিত ছাড়া এটি আমার প্রিয় উত্তর হবে। উইন্ডোজে আইপিভি 6 অ্যাড্রেসগুলি কীভাবে পাবেন তা কি কেউ আবিষ্কার করেছেন?
জিন-পল ক্যালডারোন

3
নেটিফেসগুলি পাই 3 কে সমর্থন করে না এবং এর জন্য সি সংকলক প্রয়োজন যা উইন্ডোতে পিআইটিএ হয়।
ম্যাট যোগদানকারী

4
@ ম্যাটজয়াইনার এই বিষয়গুলির কোনওটিই আর সত্য নয় (সর্বশেষ সংস্করণে পিপিআইতে উইন্ডোজ বাইনারি রয়েছে এবং পাই 3 কে সমর্থন করে)।
অ্যালাস্টার

4
@ জাঁ PaulCalderone FWIW, netifaces এর সর্বশেষ সংস্করণ আছে Windows এ সমর্থন IPv6,।
অ্যালাস্টার

47

সকেট এপিআই পদ্ধতি

দেখতে https://stackoverflow.com/a/28950776/711085

downsides:

  • ক্রস প্ল্যাটফর্ম নয়।
  • ইন্টারনেটে নির্দিষ্ট ঠিকানাগুলির অস্তিত্বের সাথে আবদ্ধ আরও ফ্যালব্যাক কোড প্রয়োজন
  • আপনি যদি নেটের পিছনে থাকেন তবে এটিও কাজ করবে না
  • সম্ভবত একটি ইউডিপি সংযোগ তৈরি করে, (সাধারণত আইএসপি'র) ডিএনএস উপলভ্যতা ছাড়াই নয় (৮.৮.৮.৮ ব্যবহারের মত ধারণার জন্য অন্যান্য উত্তর দেখুন: গুগলের (কাকতালীয়ভাবে ডিএনএস) সার্ভার)
  • নিশ্চিত করুন যে আপনি গন্তব্য ঠিকানাটি অপরিবর্তনীয়, এমন একটি সংখ্যার আইপি ঠিকানার মতো যা অব্যবহৃত হওয়ার নিশ্চয়তাযুক্ত। Fkesubdomain.google.com বা somefakewebsite.com এর মতো কিছু ডোমেন ব্যবহার করবেন না; আপনি এখনও সেই দলটিকে (এখন বা ভবিষ্যতে) স্প্যামিং এবং আপনার নিজস্ব নেটওয়ার্ক বাক্সগুলিকেও প্রক্রিয়াটিতে স্প্যামিং করে যাবেন।

প্রতিফলক পদ্ধতি

(মনে রাখবেন যে এটি স্থানীয় আইপি ঠিকানার ওপি-র প্রশ্নের উত্তর দেয় না, উদাহরণস্বরূপ, 192.168 ...; এটি আপনাকে আপনার সার্বজনীন আইপি ঠিকানা দেয় যা ব্যবহারের ক্ষেত্রে নির্ভর করে আরও পছন্দসই হতে পারে))

আপনি হোয়াটস্মিআইপি.কম (তবে একটি এপিআই সহ) এর মতো কিছু সাইটকে জিজ্ঞাসা করতে পারেন, যেমন:

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)

বা যদি পাইথন 2 ব্যবহার করে:

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)

সুবিধাদি:

  • এই পদ্ধতির একটি উল্টো দিকটি হ'ল এটি ক্রস প্ল্যাটফর্ম
  • এটি কুৎসিত NAT এর পিছনে থেকে কাজ করে (যেমন আপনার হোম রাউটার)।

অসুবিধাগুলি (এবং কর্মক্ষেত্র):

  • এই ওয়েবসাইটটি আপ হওয়া দরকার, ফর্ম্যাটটি পরিবর্তিত হবে না (প্রায় অবশ্যই হবে না) এবং আপনার ডিএনএস সার্ভারগুলি কাজ করছে। ব্যর্থতার ক্ষেত্রে অন্য তৃতীয় পক্ষের আইপি অ্যাড্রেস রিফ্লেক্টরদের জিজ্ঞাসা করেও কেউ এই সমস্যাটিকে প্রশমিত করতে পারে।
  • সম্ভাব্য আক্রমণ ভেক্টর যদি আপনি একাধিক প্রতিবিম্বকে জিজ্ঞাসা না করেন (কোনও আপোসড প্রতিফলককে আপনার ঠিকানাটি এটির মতো না বলে আপনাকে বাধা দিতে), বা যদি আপনি এইচটিটিপিএস ব্যবহার না করেন (মাঝারি-মধ্যবর্তী আক্রমণটিকে ভান করে রাখার জন্য) সার্ভার হতে)

সম্পাদনা : যদিও প্রাথমিকভাবে আমি ভেবেছিলাম এই পদ্ধতিগুলি সত্যই খারাপ (আপনি যদি অনেক ফলব্যাক ব্যবহার না করেন তবে কোডটি এখন থেকে অনেক বছর ধরে অপ্রাসঙ্গিক হতে পারে), এটি "ইন্টারনেট কি?" প্রশ্নটি উত্থাপন করে। একটি কম্পিউটারে অনেকগুলি বিভিন্ন নেটওয়ার্কের দিকে ইঙ্গিত করে অনেক ইন্টারফেস থাকতে পারে। বিষয়ের আরও বিশদ বিবরণের জন্য গুগলgateways and routes । একটি কম্পিউটার কোনও অভ্যন্তরীণ গেটওয়ের মাধ্যমে কোনও অভ্যন্তরীণ নেটওয়ার্ক অ্যাক্সেস করতে পারে বা গেটওয়ের মাধ্যমে বিশ্বব্যাপী ওয়েব অ্যাক্সেস করতে পারে উদাহরণস্বরূপ রাউটার (সাধারণত কেস)। ওপি যে স্থানীয় আইপি ঠিকানাটির বিষয়ে জিজ্ঞাসা করে সেগুলি কেবল একটি লিঙ্ক স্তরের ক্ষেত্রে সুনির্দিষ্টভাবে সংজ্ঞায়িত হয়েছে, সুতরাং আপনাকে অবশ্যই এটি নির্দিষ্ট করতে হবে ("এটি কি নেটওয়ার্ক কার্ড, বা ইথারনেট কেবল, যা আমরা কথা বলছি?") । এই প্রশ্নের উত্থাপিত হিসাবে একাধিক অ-অনন্য উত্তর থাকতে পারে। তবে ওয়ার্ল্ড-ওয়াইড ওয়েবের গ্লোবাল আইপি অ্যাড্রেসটি সম্ভবত সম্ভবত সংজ্ঞায়িত (বৃহত নেটওয়ার্ক বিভাজনের অভাবে): সম্ভবত গেটওয়ে দিয়ে ফেরার পথ যা টিএলডিগুলিতে অ্যাক্সেস করতে পারে।


আপনি কোনও NAT এর পিছনে থাকলে এটি আপনার ল্যান-প্রশস্ত ঠিকানাটি ফিরিয়ে দেবে। আপনি যদি ইন্টারনেটের সাথে সংযোগ স্থাপন করেন তবে আপনি এমন একটি ওয়েব পরিষেবাতে সংযোগ করতে পারেন যা আপনার সার্বজনীন আইপি ঠিকানাগুলির একটি ফেরত দেয়।
ফিহাগ

এটি টিসিপি সংযোগ তৈরি করে না কারণ এটি একটি ইউডিপি সংযোগ তৈরি করে।
অনুজ গুপ্ত

2
সকেট এপিআই সংস্করণে বিকল্প হিসাবে, এস.সিটসকপ্ট (সকেট.সোল_সোকકેટ, সকেট.সো_ব্রোডসিএসটি, 1); এসকনেক্ট (('<< ব্রডকাস্ট> ', 0)) ডিএনএস চেহারা এড়াতে। (আমার মনে হয় ফায়ারওয়াল হলে কোনও সম্প্রচারে সমস্যা হতে পারে)
dlm

45

কম্পিউটারে যদি ইন্টারনেটে কোনও রুট থাকে তবে এটি / etc / হোস্টগুলি সঠিকভাবে সেট না করা সত্ত্বেও, সর্বদা পছন্দসই স্থানীয় আইপি ঠিকানা পেতে কাজ করবে ।

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একটি গুগল ডিএনএস সার্ভার কি আমরা একটি স্থানীয় ডিএনএস সার্ভার দিয়ে এটি করতে পারি?
সিয়াস্তো পাইকারজ

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
সকেটটি কার্নেলের সাথে যোগাযোগের জন্য একটি এফডি পেতে খোলা হয় (মাধ্যমে ioctl)। সকেট সেই ইন্টারফেসের সাথে আবদ্ধ নয় যার জন্য আপনি অ্যাডারের তথ্য চান - এটি ইউজারস্পেস এবং কার্নেলের মধ্যে একটি যোগাযোগ ব্যবস্থা। en.wikipedia.org/wiki/Ioctl lxr.free-electrons.com/source/net/socket.c
টিএমসি

2
পাইথন 3 এ একটি পরিবর্তন করে কাজ করে: struct.pack('16sH14s', iface, socket.AF_INET, '\x00'*14)প্রতিস্থাপন করা উচিতstruct.pack('16sH14s', iface.encode('utf-8'), socket.AF_INET, b'\x00'*14)
পেপোলুয়ান

1
@ ক্রিশ্চিয়ানফিশার ioctlএকটি লিগ্যাসি ইন্টারফেস যা আমি বিশ্বাস করি না যে আইপিভি 6 সমর্থন করে এবং সম্ভবত কখনও তা করবে না। আমি মনে করি 'ডান' পথটি নেট লিঙ্কের মাধ্যমে যা পাইথনের খুব সোজা নয়। আমি মনে করি libc এর সেই ফাংশন থাকা উচিত getifaddrsযা অজগর ctypesমডিউলের মাধ্যমে অ্যাক্সেস করা যায় যা কাজ করতে পারে - man7.org/linux/man-pages/man3/getifaddrs.3.html
tMC

1
@ ম্যাডি আইওটিএল একটি উত্তরাধিকারসূচক ইন্টারফেস যা আমি বিশ্বাস করি না যে আইপিভি 6 সমর্থন করে এবং সম্ভবত কখনও তা করবে না। আমি মনে করি 'ডান' পথটি নেট লিঙ্কের মাধ্যমে যা পাইথনের খুব সোজা নয়। আমি মনে করি libc এর ফাংশন জেটিফাড্ডার থাকা উচিত যা পাইথনস টাইপস মডিউলের মাধ্যমে অ্যাক্সেস করা যেতে পারে যা কাজ করতে পারে - man7.org/linux/man-pages/man3/getifaddrs.3.html
tMC

27

আমি নিম্নলিখিত মডিউল ব্যবহার করছি:

#!/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 ভিত্তিক ল্যানে থাকা সিস্টেমে ব্যবহারের উদ্দেশ্যে উইন্ডোজ এবং লিনাক্স (এবং এর জন্য অতিরিক্ত মডিউলগুলির প্রয়োজন নেই) দিয়ে পরীক্ষা করা হয়েছে।

ইন্টারফেস নামের স্থির তালিকাটি সাম্প্রতিক লিনাক্স সংস্করণগুলির জন্য কাজ করে না, যা আলেকজান্ডারের নির্দেশিত হিসাবে অনুমানযোগ্য ইন্টারফেসের নামগুলি সংক্রান্ত systemd v197 পরিবর্তনটি গ্রহণ করেছে । এই ধরনের ক্ষেত্রে, আপনাকে নিজের সিস্টেমে ইন্টারফেসের নামের সাথে তালিকাকে ম্যানুয়ালি পরিবর্তন করতে হবে, বা নেটিফেসগুলির মতো অন্য সমাধান ব্যবহার করতে হবে ।


2
এটি নতুন অনুমানযোগ্য লিনাক্স ইন্টারফেসের নামগুলির সাথে অসঙ্গত, যেমন enp0s25। আরও তথ্যের জন্য, wiki.archlinux.org/index.php/Network_Configration# ডিভাইস_নাম
আলেকজান্ডার

2
আমি পাইথন ৩.৪ ব্যবহার করছিলাম এবং 'স্ট্রাকটপ্যাক (...)' অংশটি 'স্ট্রাক্টপ্যাক' ('256s', বাইটস (ifname [: 15], 'utf-8')) এ পরিবর্তন করা দরকার। : এই প্রশ্ন দেখতে পাবেন stackoverflow.com/q/27391167/76010
Bakanekobrain

1
রাস্পবিয়ান ডাব্লু / পাইথন ২.7.৩ এ - বাইটস () ২ য় যুক্তি পছন্দ করে নি। তবে এটি কাজ করেছে: struct.pack('256s', bytes(ifname[:15]))
colm.anseo

24

আমি এটি আমার উবুন্টু মেশিনে ব্যবহার করি:

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

এটি কাজ করে না।


সুন্দর এবং সহজ। অ্যামাজনের লিনাক্স এএমআই-তেও কাজ করে তবে আমি রুট হলেই। অন্যথায় আমি একটি ত্রুটি পেয়ে যাব: 'sh: ifconfig: কমান্ড পাওয়া যায় নি'
IgorGanapolsky

সুতরাং আপনার "/ এসবিিন / আইফনফিগ" ব্যবহার করা উচিত গাভালেটজ বলেছিলেন। এটি রেড হ্যাট 4.1.2-48 এও কাজ করে।
ইগোরগানাপলস্কি

7
২.6 থেকে অবহেলিত। কমান্ডগুলি চালাতে সাবপ্রসেস মডিউলটি ব্যবহার করুন ।
কলিন ডানক্লাউ

5
এবং ifconfig পাশাপাশি অবচয় করা হয়। Iproute2 ব্যবহার করুন।
হেলমুট গ্রোহনে

সমস্ত আইপিএস পান: sh আমদানি করুন; [আইপি.স্প্লিট () [1] [5:] ফিল্টার আইপি জন্য (ল্যাম্বদা এক্স: এক্স ইন 'ইনড অ্যাডার', sh.ifconfig ()। বিভক্ত ("\ n"))]
গ্যাব্রিয়েল লিটম্যান

20

আপনি যদি বাহ্যিক প্যাকেজগুলি ব্যবহার করতে না চান এবং ইন্টারনেট সার্ভারের বাইরের উপর নির্ভর করতে না চান তবে এটি সাহায্য করতে পারে। এটি একটি কোডের নমুনা যা আমি গুগল কোড অনুসন্ধানে পেয়েছি এবং প্রয়োজনীয় তথ্য ফিরিয়ে দিতে সংশোধন করেছি:

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
এই লিপিটি প্রথম ঠিকানাটি ফেরত দেওয়ার পরে আমার মেশিনে ব্যর্থ। ত্রুটিটি হ'ল "অ্যাট্রিবিউটআরার: 'এলপি_আইপি_এডিডিআর_আরটিংসিং' অবজেক্টটির কোনও 'ipAddress' বৈশিষ্ট্য নেই" আমার সন্দেহ হয় আইপিভি 6 ঠিকানার সাথে এর কিছু আছে।
জেসন আর। কুম্বস

1
এটি দেখা যাচ্ছে যে প্রথম আইপি ঠিকানা ব্যতীত অন্য কোনও কিছুর জন্য, অ্যাডনোডকে অবহেলা করা হয়নি। উদাহরণস্বরূপ লুপটিতে আরও একটি লাইন যুক্ত করুন এবং এটি আমার জন্য কাজ করে: অ্যাডনোড = অ্যাডনোডকন্টেন্টস
জেসন আর।

18

ডেবিয়ানে (পরীক্ষিত) এবং আমি বেশিরভাগ লিনাক্সের সন্দেহ করি ..

import commands

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

এমএস উইন্ডোজে (পরীক্ষিত)

import socket

socket.gethostbyname(socket.gethostname())

1
hostname: illegal option -- I\nusage: hostname [-fs] [name-of-host]
ম্যাকোজে

18

এমন একটি সংস্করণ যা আমি বিশ্বাস করি না যে এটি পোস্ট করা হয়েছে। আমি উবুন্টু 12.04 এ পাইথন 2.7 দিয়ে পরীক্ষা করেছি।

এই সমাধানটি এখানে পেয়েছে: http://code.activestate.com/recines/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 এ কাজ করে; স্ট্রিংয়ের বাইটগুলি হওয়া দরকার: >>> सॉকেট.এনইট_টোয়া (fcntl.ioctl (s.fileno (), 0x8915, স্ট্রাক্টপ্যাক ('256s', 'enp0s31f6' [: 15]। এনকোড ('utf-8')) )) [20:24]) '192.168.1.1'
সিউজার

12

নিনজেকেকোর উত্তরের ভিন্নতা। এটি এমন কোনও ল্যানে কাজ করা উচিত যা ইউডিপি সম্প্রচারের অনুমতি দেয় এবং ল্যান বা ইন্টারনেটে কোনও ঠিকানার অ্যাক্সেসের প্রয়োজন হয় না।

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>বৈধ হোস্টনাম? !! এই ধরণের মৌখিক হোস্টনাম কতটি বৈধ?
দেব আগরওয়াল

এটি আমার জন্য উবুন্টু 20.04-এ কাজ করে - 192.168.0.24 পেয়ে 127.0.0.1 নয়
লুইস মরিস

8

আমি আশঙ্কা করছি যে অন্য কোনও কম্পিউটারের সাথে সংযোগ স্থাপন এবং এটি আপনাকে আপনার আইপি ঠিকানাটি প্রেরণ করা ছাড়া এটি করার কোনও ভাল প্ল্যাটফর্মের স্বাধীন উপায় নেই। উদাহরণস্বরূপ: findmyipadress । নোট করুন যে আপনার যদি NAT এর পিছনে থাকা কোনও আইপি ঠিকানা প্রয়োজন হয় তবে যদি আপনি যে কম্পিউটারে সংযোগ করছেন সেটিও NAT এর পিছনে না থাকে this

এখানে একটি সমাধান যা লিনাক্সে কাজ করে: একটি নেটওয়ার্ক ইন্টারফেসের সাথে সম্পর্কিত আইপি ঠিকানাটি পান


8

কমান্ড লাইন ব্যবহারের মাধ্যমে "পরিষ্কার" আউটপুট উত্পাদন করার একটি সহজ উপায়:

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

এটি সিস্টেমে সমস্ত আইপিভি 4 ঠিকানা প্রদর্শন করবে।


1
এটি সমস্ত আইপিভি 4 অ্যাড্রেস প্রদর্শন করবে না, কারণ আইফনফিগ কেবল আপনাকে প্রাথমিকগুলি সম্পর্কে বলে। সমস্ত ঠিকানা দেখতে আপনাকে আইপ্রেট 2 থেকে "আইপি" ব্যবহার করতে হবে।
হেলমুট গ্রোহনে

এটি স্ট্যান্ডার্ড লাইব্রেরি জিজ্ঞাসা করে এমন প্রশ্নের জন্য প্রচুর শেলের একটি জাহান্নাম… এছাড়াও, ifconfig কে পার্সিং না হয় বহনযোগ্য নয় এমনকি একটি মেশিনেও নির্ভরযোগ্যভাবে কাজ করবে না।
ডোমিনিক জর্জে

7

এফওয়াইআই আমি পদ্ধতিটি যাচাই করতে পারি:

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

ওএস এক্স (10.6,10.5), উইন্ডোজ এক্সপি এবং সুশাসিত আরএইচইএল বিভাগের সার্ভারে কাজ করে। এটি খুব ন্যূনতম সেন্টোস ভিএম-তে কাজ করে নি যে আমি কিছু কার্নেল হ্যাকিং করছি। সুতরাং উদাহরণস্বরূপ আপনি কেবল একটি 127.0.0.1 ঠিকানার জন্য পরীক্ষা করতে পারেন এবং সেক্ষেত্রে নিম্নলিখিতটি করুন:

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

এবং তারপরে আউটপুট থেকে আইপি ঠিকানা পার্স করুন। এটি লক্ষ করা উচিত যে ডিফল্টরূপে ifconfig সাধারণ ব্যবহারকারীর PATH তে নেই এবং সে কারণেই আমি কমান্ডটিতে পুরো পথটি দিয়েছি। আশা করি এটা কাজে লাগবে.


7

এটি আনকউএনটেকের উত্তরের একটি বৈকল্পিক - এটি একটি get_local_addr()ফাংশন সরবরাহ করে, যা হোস্টের প্রাথমিক ল্যান আইপি ঠিকানা প্রদান করে returns আমি এটি পোস্ট করছি কারণ এটি বেশ কয়েকটি জিনিস যুক্ত করে: আইপিভি 6 সমর্থন, ত্রুটি পরিচালনা, লোকালহোস্ট / লিঙ্কলোকাল অ্যাডারদের উপেক্ষা করে এবং সংযোগের জন্য একটি টেস্টনেট অ্যাডার (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
জেমি লিন্ডসে

@ জ্যামি লিন্ডসে আপনার ওএস, নেটওয়ার্ক কনফিগারেশন সম্পর্কে কিছু বিশদ আছে? এছাড়াও, get_local_addr(remove="www.google.com")ফিরে কি মত কিছু আছে ? লগিং socket.error_get_local_addr দ্বারা নিক্ষিপ্ত () diagnostically সাহায্য করতে পারে।
এলি কলিন্স

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

1
হুম ... দুটি এনআইসি সহ একটি সার্ভারে এটি নির্ধারিত আইপি ঠিকানাগুলির মধ্যে একটি দেয় তবে তিনবার পুনরাবৃত্তি হয়। আমার ল্যাপটপে এটি '127.0.1.1' দেয় (তিনবার পুনরাবৃত্তি ...) ...
ব্রায়েন

['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 ম্যাসেজটির উত্তর দিতে পারে 'আপনার আইপি ঠিকানাটি xxx'।
নিকোলাস Defranoux

4

127.0.1.1 হয় আপনার আসল IP ঠিকানা। আরও সাধারণভাবে বলতে গেলে, একটি কম্পিউটারে অনেকগুলি আইপি ঠিকানা থাকতে পারে। আপনি ব্যক্তিগত নেটওয়ার্কগুলির জন্য সেগুলি ফিল্টার করতে পারেন - 127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12 এবং 192.168.0.0/16।

তবে সমস্ত আইপি ঠিকানা পাওয়ার কোনও ক্রস-প্ল্যাটফর্ম উপায় নেই। লিনাক্সে, আপনি SIOCGIFCONFioctl ব্যবহার করতে পারেন ।


2
তার অর্থ তার বাহ্যিক দৃশ্যমান আইপি। 127। *। *। * পরিসরটি সাধারণত লোকালহোস্ট বা অভ্যন্তরীণ নেটওয়ার্ককে বোঝায় যা স্পষ্টভাবে সে যা চায় তা নয়।
সেরিন

4

আইপি কমান্ড ব্যবহার করা কমান্ড সংস্করণটির সামান্য পরিমার্জন এবং আইপিভি 4 এবং আইপিভি 6 ঠিকানা ফেরত দেয়:

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

আচ্ছা আপনার বর্তমান আইপি ঠিকানা জানতে আপনি জিএনইউ / লিনাক্সে "আইপি রুট" কমান্ডটি ব্যবহার করতে পারেন।

এটি রাউটার / মডেমটিতে চলমান ডিএইচসিপি সার্ভারের দ্বারা ইন্টারফেসটিকে দেওয়া আইপি দেখায়। সাধারণত "192.168.1.1/24" হ'ল স্থানীয় নেটওয়ার্কের আইপি যেখানে "24" অর্থ মুখোশের ব্যাপ্তির মধ্যে ডিএইচসিপি সার্ভারের দ্বারা প্রদত্ত পজিবল আইপি ঠিকানার পরিসর।

এখানে একটি উদাহরণ রয়েছে: নোট করুন যে পাইনিটিফাইটি আমার পয়েন্টটি সোজা করার জন্য কেবল একটি সংযোজন এবং একেবারেই প্রয়োজন হয় না

#! /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 বা এমনকি পাইপ ব্যবহার করে পাইনিটিফাই ইনস্টল করতে পারেন:

easy_install py-notify

অথবা

pip install py-notify

বা পাইথন স্ক্রিপ্ট / ইন্টারপ্রেটারের মধ্যে

from pip import main

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

4

আপনি যদি নিজের লোকালহোস্টের আইপি ঠিকানার চেয়ে পৃথক কোনও আইপিভি 4 ঠিকানা খুঁজছেন তবে 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, কোড এখনও আপনার স্থানীয় IP ঠিকানা দিতে হবে।


4

লিনাক্সের জন্য, আপনি শুধু ব্যবহার করতে পারেন check_outputএর hostname -Iতাই মত সিস্টেম কমান্ড প্রয়োগ করুন:

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

গুগলারের জন্য, আমি জানি প্রশ্নটি ক্রস প্ল্যাটফর্ম সমাধানের জন্য ছিল
ক্যাস্পার স্কাইটি অ্যান্ডারসন

3

দ্রষ্টব্য: এটি স্ট্যান্ডার্ড লাইব্রেরি ব্যবহার করছে না, তবে বেশ সহজ।

$ পিপ ইনস্টল pif

from pif import get_public_ip
get_public_ip()

3
প্রশ্নগুলি stdlib ব্যবহার করে আইপি অনুসন্ধানের বিষয়ে ছিল
আলেকজান্দ্রু চিরিলা

3

নেটিফেসগুলি পাইপ এবং ইজি_সিনস্টলের মাধ্যমে উপলব্ধ। (আমি জানি, এটি বেসে নেই, তবে এটি ইনস্টল করার পক্ষে মূল্যবান হতে পারে))

প্ল্যাটফর্মগুলি জুড়ে নেটফেসগুলির কিছু অদ্ভুততা রয়েছে:

  • লোকালহোস্ট / লুপ-ব্যাক ইন্টারফেস সর্বদা অন্তর্ভুক্ত নাও হতে পারে (সাইগউইন)।
  • ঠিকানাগুলি প্রতি প্রোটোকল তালিকাভুক্ত করা হয় (যেমন, আইপিভি 4, আইপিভি 6) এবং প্রোটোকলগুলি প্রতি ইন্টারফেসের তালিকাভুক্ত হয়। কিছু সিস্টেমে (লিনাক্স) প্রতিটি প্রোটোকল-ইন্টারফেস জোড়ের নিজস্ব সংযুক্ত ইন্টারফেস থাকে (ইন্টারফেস_ নাম ব্যবহার করে: নোটেশন ব্যবহার করা হয়) অন্য সিস্টেমে (উইন্ডোজ) প্রতিটি প্রোটোকলের জন্য একক ইন্টারফেসের ঠিকানাগুলির তালিকা থাকে। উভয় ক্ষেত্রেই একটি প্রোটোকল তালিকা রয়েছে তবে এটিতে কেবল একটি একক উপাদান থাকতে পারে।

এখানে খেলতে এখানে কিছু নেটিফেস কোড রয়েছে:

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

নতুন পরিচয় হওয়া অ্যাসিনসিও প্যাকেজটি ব্যবহার করে পাইথন ৩.৪ সংস্করণ।

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

এটি আনকউএনটেকের দুর্দান্ত উত্তরের উপর ভিত্তি করে ।


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()
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.