基本上我有一个在嵌入式系统(基于 Buildroot)上运行的 Python 脚本。 python脚本在启动时运行,但我不能保证那时互联网连接会建立(基于pppd),因为该设备可能不在有手机信号的区域。
我发现,如果 python 代码在计算机上建立互联网连接之前启动,即使在建立连接之后,python 代码仍然无法解析名称。[Errno -3] Temporary failure in name resolution
当套接字尝试连接时出现错误。我让它工作的唯一方法是在启动 python 代码之前至少建立一次互联网连接。
在建立互联网连接后,Python 代码可能会查找至少一次,系统会发生哪些变化?有什么我可以在启动时设置的东西,这样就不会发生这种情况吗?
答案1
您可以使用 pppd 提供的脚本挂钩,在 ip 启动后调用您的脚本。例如(来自 pppd 联机帮助页)
/etc/ppp/ip-up
A program or script which is executed when the link is available for
sending and receiving IP packets (that is, IPCP has come up). It is
executed with the parameters
interface-name tty-device speed local-IP-address remote-IP-address ipparam
当你从那里启动你的 python 脚本时,你应该没问题。
答案2
/etc/resolv.conf
大多数程序仅在启动或首次进行网络访问时读取一次系统 DNS 配置(在 中)。如果配置发生变化,他们不会重新读取配置。
看起来,在您的系统上,当网络上升时,DNS 配置会发生变化(可能从未配置更改为已配置 DNS 服务器)。这是很常见的,如果系统并不总是连接到同一网络,则这是不可避免的。
确保程序不受影响的一种方法是运行本地 DNS 缓存服务器。这样,应用程序的 DNS 配置可以是静态的(始终nameserver 127.0.0.1
在 中/etc/resolv.conf
),并且只需要告知 DNS 缓存服务器有关网络连接提供的服务器的信息。域名解析是一个常见的选择,尤其是在嵌入式系统上(如果您有 Linux 路由器,它可能运行 dnsmasq)。如果您使用 Buildroot 构建自己的映像,请包含该dnsmasq
包。如果您有一个没有 dnsmasq 的预构建映像,通过Builtroot 安装 dnsmasq 可能仍然是最好的选择,但我不熟悉 Buildroot,所以我无法解释如何做到这一点。
答案3
要强制刷新解析表,您可以运行以下命令(在 Linux 上):
import ctypes
libc = ctypes.cdll.LoadLibrary('libc.so.6')
res_init = libc.__res_init
res_init()