Нахождение локальных IP-адресов с помощью stdlib Python под Debian jessie

Я пишу программу распределенных систем в Python, и в этой программе я должен знать локальный IP-адрес..., например, 168.192.... 10.13..... и т.д., не 127.0.0.1 или имя хоста.

Я нашел следующее решение на stackoverflow

https://stackoverflow.com/questions/166506/finding-local-ip-addresses-using-pythons-stdlib

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

Когда я выполняю это на своем ноутбуке Debian jessie, я добираюсь 127.0.0.1, однако, мой друг, который использует Fedora на его машине, получает желаемый IP-адрес, когда он запускает тот же скрипт (например, 168.192..)

Я предпочитаю использовать решение выше, если это возможно, для получения локального IP-адреса, потому что большинство других предлагаемых решений является или взломами или невероятный долго...

Есть ли что-то, что я могу установить на своем ноутбуке Debian jessie, таким образом, что Python возвратит корректный локальный IP-адрес?

  • использование debian jessie
  • python 3
  • соединен для сетей (.. и компьютер включен)... ;)
  • /etc/hosts в настоящее время содержит:

127.0.0.1 localhost 127.0.0.1 debianASUS ::1 localhost ip6-localhost ip6-loopback ff02::1 ip6-allnodes ff02::2 ip6-allrouters

2
задан 23 May 2017 в 15:41
2 ответа

Рассматривали ли вы возможность передачи решения конечному пользователю во время выполнения с помощью параметра конфигурации? Это стандартная практика для данной проблемы.

Причина в том, что не существует систематического надежного способа определения «» локального IP-адреса (хост может быть многосетевым, может работать с двойным стеком v4 / v6, VPN и т. Д. ..). Конфигурация среды выполнения облегчит работу системного администратора!

2
ответ дан 3 December 2019 в 09:34

Самый надежный способ найти IP-адрес, который ваш хост будет использовать для связи, - использовать getsockname на подключенном сокете UDP. В случае UDP системный вызов connect не связан с сетевым взаимодействием.

Вот функция Python, которую я написал ранее для аналогичной цели. Если вы не знаете заранее, с каким удаленным IP-адресом вы будете связываться, вам следует искать тот, который будет использовать маршрут по умолчанию. Если вы уже знаете, с каким удаленным IP-адресом вы будете связываться, то лучше использовать этот IP-адрес в вызове connect.

def my_ip():
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    try:
        s.connect(('192.0.0.8', 1027))
    except socket.error:
        return None
    return s.getsockname()[0]

С небольшими изменениями эта функция может быть адаптирована для возврата адреса IPv6, а не IPv4:

def my_ipv6():
    s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
    try:
        s.connect(('2001:db8::', 1027))
    except socket.error:
        return None
    return s.getsockname()[0]
3
ответ дан 3 December 2019 в 09:34

Теги

Похожие вопросы