Python не получает IP, если кабель подключен после запуска скрипта

Я надеюсь, что это не пересекает территорию суперпользователя.

Итак, у меня есть встроенный linux, где системные процессы, естественно, довольно раздеты. Я не совсем уверен, какой системный процесс отслеживает физический уровень и запускает клиент DHCP, когда сетевой кабель подключен, но я сам его создал. Is Проблема в том, что если у меня есть скрипт на Python, использующий http-соединения и работающий до того, как у меня есть IP-адрес, он никогда не получит соединение. Даже после того, как у меня есть действующий IP, питон все еще имеет

"Временная ошибка в разрешении имени"

Итак, как я могу заставить python реализовать новое доступное соединение без перезапуска скрипта?

В качестве альтернативы, я пропускаю некоторые нормальные процедуры, которые Linux работает нормально при подключении к сетевому кабелю.

Я использую клиент dhcp udhcpc, а версия python 2.6. Использование httplib для соединений.

3 ответа

Похоже, httplib кэши /etc/resolv.conf который обновляется после того, как ваш клиент DHCP получает IP.

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

Кроме того, вы можете попытаться в вашем скрипте Python не открывать какие-либо сокетные соединения, пока вы не получите IP-адрес и не /etc/resolv.conf обновлено.

редактировать

httplib использует socket.create_connection() который после некоторого поиска нашел кеш /etc/resolv.conf, (Ну, похоже, что встроенная версия libc фактически выполняет кеширование).

Вы можете попробовать решение SugarLabs, хотя я не могу говорить о его эффективности.

Может случиться так, что один из модулей python кэширует состояние сети, и поэтому он не использует последние настройки. Попробуйте перезагрузить все модули, связанные с сетью. Простой пример этого:

import sys, socket, urllib

for i in [sys, socket, urllib]:
    reload(i)

если это не сработает, оглянись в sys.modules чтобы увидеть, что еще было импортировано, и попробуйте больше модулей там. Более экстремальной версией перезагрузки был бы приведенный ниже код, который вы можете попробовать в качестве последней попытки.

код

import sys
print 'reloading %s modules ' % len(sys.modules)
for name, module in sys.modules.items():
    try:
        reload(module)
    except:
        print 'failed to import %s' % name

выход

reloading 42 modules 
failed to import __main__
failed to import encodings.encodings
failed to import encodings.codecs
failed to import lazr
failed to import encodings.__builtin__

После долгих исследований проблема glibc, предложенная Джедвардсом, казалась проблемой. Я не нашел решения, но сделал обходной путь для моего варианта использования. Учитывая, что я использую только один URL, я добавил свой собственный resolv.file. Небольшой демон получает IP-адрес URL, когда PHY сообщает о подключенном кабеле. Этот IP-адрес сохраняется в "моем собственном resolv.conf". Из этого файла скрипт Python извлекает IP-адрес, который будет использоваться для сообщений.

Не очень хорошее решение, но решение.

Другие вопросы по тегам