多网段切换导致DNS域名解析失败问题处理
Posted 谁吃薄荷糖
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多网段切换导致DNS域名解析失败问题处理相关的知识,希望对你有一定的参考价值。
文章目录
🔴问题描述:
设备有LAN和WIFI两种网络方式,测试时LAN和WIFI分别连接在两个不同的路由器上,切换两个网络(只启用LAN或者WIFI)时发现设备的mqtt程序重连服务器会失败(服务器地址使用的是域名)。
🟠问题排查:
初步排查时发现重启mqtt程序,可以正常连接。但是使用mqtt的断网重连功能发现就不行。最后研读mqtt源码,发现是调用
getaddrinfo
函数失败了,顺藤摸瓜去排查这个函数与DNS相关的地方。
🟡问题解决:
需要在DNS解析失败时,重新加载一下DNS。所以在mqtt断链的回调里加入了res_init()
函数,问题解决,重连成功。
🟢知识扩展:
如果在程序中调用getaddrinfo
和getnameinfo
来获取域名对应的IP,在同一进程中,上一次成功获取的结果会被保留下来,即使在下一次调用之前disable了DNS并清空了系统的DNS缓存,下一次仍然能够解析出正确的IP。此时需要在调用这两个函数之前用res_init()
函数来清空他们自己保留的缓存。
🔵res_init() 简介:
作用:
搜索默认域名和 Internet 地址。
所属库:
标准 C 库 ( libc.a
)
示例:
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <resolv.h>
void res_init ( )
描述
res_init子例程读取/etc/resolv.conf文件以获取默认域名和运行名称服务器的初始主机的 Internet 地址。
注意:如果/etc/resolv.conf文件不存在,res_init子例程会尝试使用本地/etc/hosts文件进行名称解析。如果系统没有使用域名服务器,则/etc/resolv.conf文件不应该存在。即使系统正在使用名称服务器,系统上也应该存在/ etc/hosts文件。在这种情况下,该文件应包含系统运行所需的主机 ID,即使名称服务器未运行也是如此。
res_init子例程是构成解析器的一组子例程之一,解析器是一组将域名转换为 Internet 地址的函数。所有解析器子例程都使用/usr/include/resolv.h文件,该文件定义了_res结构。res_init子例程将域名信息存储在_res结构中。三个环境变量LOCALDOMAIN、RES_TIMEOUT和RES_RETRY影响与_res结构相关的默认值。
所有包含res_init子例程的应用程序都必须在编译时将_BSD宏设置为特定值。可接受的值为 43 和 44。此外,所有套接字应用程序都必须包含 BSD libbsd.a库。
相关文件
路径 | 描述 |
---|---|
/etc/resolv.conf | 包含名称服务器和域名。 |
/etc/hosts | 包含网络中主机的主机名及其地址。此文件用于将主机名解析为 Internet 地址。 |
🟣引经据典:
https://blog.csdn.net/weixin_39530839/article/details/116778660?utm_source=app&app_version=5.3.0
https://www.ibm.com/docs/zh/aix/7.3?topic=r-res-init-subroutine
以上是关于多网段切换导致DNS域名解析失败问题处理的主要内容,如果未能解决你的问题,请参考以下文章