سؤال

أنا أعمل على إنشاء تطبيق خادم بسيط مع Python ، وأحاول الحصول على عنوان IP لربط مأخذ التوصيل إلى. مثال نظرت إليه يستخدم هذا:

HOST = gethostbyaddr(gethostname())

مع المزيد من المعالجة بعد ذلك ، يجب أن تعطيني فقط IP المضيف كسلسلة. هذا يجب أن يعيد عنوان IPv4. ولكن عندما أقوم بتشغيل هذا الرمز ، فإنه يعيد عنوان IPv6 الخاص بي. لماذا يفعل هذا وكيف يمكنني الحصول على عنوان IPv4 الخاص بي؟

إذا كانت ذات صلة ، فأنا أستخدم Windows Vista و Python 2.5

هل كانت مفيدة؟

المحلول

الحصول على عنوان IP الخاص بك أصعب مما قد تعتقد.

يفحص هذا الجواب أعطيت للطريقة الموثوقة التي وجدتها.

إليك ما تقوله الإجابة في حال لم تحب النقر على الأشياء:

استخدم ال netifaces وحدة. نظرًا لأن الشبكات معقدة ، فقد يكون استخدام Netifaces أمرًا صعبًا بعض الشيء ، ولكن إليك كيفية القيام بما تريد:

>>> import netifaces
>>> netifaces.interfaces()
['lo', 'eth0']
>>> netifaces.ifaddresses('eth0')
{17: [{'broadcast': 'ff:ff:ff:ff:ff:ff', 'addr': '00:11:2f:32:63:45'}], 2: [{'broadcast': '10.0.0.255', 'netmask': '255.255.255.0', 'addr': '10.0.0.2'}], 10: [{'netmask': 'ffff:ffff:ffff:ffff::', 'addr': 'fe80::211:2fff:fe32:6345%eth0'}]}
>>> for interface in netifaces.interfaces():
...   print netifaces.ifaddresses(interface)[netifaces.AF_INET]
...
[{'peer': '127.0.0.1', 'netmask': '255.0.0.0', 'addr': '127.0.0.1'}]
[{'broadcast': '10.0.0.255', 'netmask': '255.255.255.0', 'addr': '10.0.0.2'}]
>>> for interface in netifaces.interfaces():
...   for link in netifaces.ifaddresses(interface)[netifaces.AF_INET]:
...     print link['addr']
...
127.0.0.1
10.0.0.2

يمكن جعل هذا أكثر قابلية للقراءة مثل هذا:

from netifaces import interfaces, ifaddresses, AF_INET

def ip4_addresses():
    ip_list = []
    for interface in interfaces():
        for link in ifaddresses(interface)[AF_INET]:
            ip_list.append(link['addr'])
    return ip_list

إذا كنت تريد عناوين IPv6 ، فاستخدم AF_INET6 بدلاً من AF_INET. إذا كنت تتساءل لماذا netifaces يستخدم القوائم والقواميس في جميع أنحاء المكان ، ولأن جهاز كمبيوتر واحد يمكن أن يحتوي على NIC متعددة ، ويمكن لكل NIC أن يكون له عناوين متعددة ، وكل عنوان له مجموعة من الخيارات الخاصة به.

نصائح أخرى

إن IPv6 له الأسبقية على IPv4 لأنها العائلة الأحدث ، وهذا ما تريده عمومًا إذا كان اسم المضيف الخاص بك مرتبطًا بعائلات متعددة. يجب أن تستخدم getaddrinfo للحل المستقل للعائلة ، إليك مثال ،

import sys, socket;
host = socket.gethostname();
result = socket.getaddrinfo(host, None);
print "family:%i socktype:%i proto:%i canonname:%s sockaddr:%s"%result[0];
result = socket.getaddrinfo(host, None, socket.AF_INET);
print "family:%i socktype:%i proto:%i canonname:%s sockaddr:%s"%result[0];
result = socket.getaddrinfo(host, None, socket.AF_INET6);
print "family:%i socktype:%i proto:%i canonname:%s sockaddr:%s"%result[0];

وهو ما يلي على مضيف مزدوج المكوّن ما يلي ،

family:10 socktype:1 proto:6 canonname: sockaddr:('2002:dce8:d28e::31', 0, 0, 0)
family:2 socktype:1 proto:6 canonname: sockaddr:('10.6.28.31', 0)
family:10 socktype:1 proto:6 canonname: sockaddr:('2002:dce8:d28e::31', 0, 0, 0)

gethostbyaddr() يأخذ عنوان IP كمعلمة ، وليس اسم مضيف ، لذلك فوجئت أنه يعمل على الإطلاق دون إلقاء استثناء. إذا كنت تعني بدلاً من ذلك gethostbyname(), ، ثم تكون نتائجك أكثر إثارة للدهشة ، لأن هذه الوظيفة تدعي عدم دعم IPv6. إجابة هارلي يشرح كيفية الحصول على عنوان IP الخاص بك بشكل صحيح.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top