kas*_*eia 5 c linux networking archlinux getaddrinfo
我正在编写一个C应用程序,它在启动时作为systemd服务运行(发行版:Arch Linux),并且应该连接到服务器.由于应用程序在引导时运行,因此最终会发生网络连接尚未建立.这自然导致第一个功能失败,需要一个,在我的情况下getaddrinfo.
所以我认为我只会编写一个循环,它会重复调用,getaddrinfo直到网络准备好后它才会成功.不幸的是,我发现即使在建立连接后getaddrinfo仍然失败name or service not known.
我能够通过其主机名ping服务器,但getaddrinfo仍然不会这样做.如果我停止应用程序并再次运行它,一切正常.如果在第一次呼叫之前已建立网络连接,则也getaddrinfo可以正常工作.
显然,如果getaddrinfo由于网络没有准备就失败一次,它将永远失败.似乎没有意识到现有的连接.使用不推荐使用时gethostbyname,行为是相同的.
这种行为的原因是什么?有没有办法强制getaddrinfo刷新内部变量(如果存在)或类似内容,这可能解释为什么函数仍然认为没有连接?是否有其他功能我应该先调用以检查网络是否准备好了?
我想避免等待一段时间的延迟,期待网络之后连接.我还希望从我的应用程序中检查连接,而不是首先检查bash脚本然后启动应用程序.
您可以通过编译以下测试程序并按照以下说明来理解答案:
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
while (1)
{
struct addrinfo *res;
int rc=getaddrinfo(argv[1], "http", NULL, &res);
printf("getaddrinfo returned %d\n", rc);
if (rc == 0)
freeaddrinfo(res);
sleep(1);
}
}
Run Code Online (Sandbox Code Playgroud)
在运行此测试程序之前:
/etc/resolv.conf为/etc/resolv.conf.save./etc/resolv.conf.save为/etc/resolv.conf.当您断开网络连接并重新连接时,您的网络堆栈会相应地重写和更新/etc/resolv.conf。C 库中的 DNS 解析器需要此配置文件。C 库从/etc/resolv.conf第一次开始读取 DNS 配置,并将其缓存。它不会在每次查找时检查 的内容是否/etc/resolv.conf已更改。
最后:
res_init()中定义的调用resolv.h,阅读相应的手册页,看看会发生什么。这就是你的答案。