使用getnameinfo()自定义sockaddr_in6反向域名解析失败排查
问题修复方案
你的代码存在两个关键问题,导致getnameinfo()返回错误码-6(对应EAI_FAMILY错误,即地址结构长度不匹配或地址族解析失败):
核心错误点
- 地址结构长度传递错误:你传给
getnameinfo()的第二个参数是sizeof(sa),但sa是sockaddr*类型的指针,sizeof(sa)得到的是指针本身的大小(通常4/8字节),而非实际的sockaddr_in6结构体大小。这会让函数无法正确解析地址结构,触发地址族相关错误。 - 结构体未完整初始化:
sockaddr_in6结构体存在未初始化的字段(如sin6_port),可能引发未定义行为,干扰函数正常执行。
修复后的代码
#include <stdio.h> #include <netdb.h> #include <arpa/inet.h> #include <cstring> #include <iostream> int main(int argc, char* argv[]) { const char* presentation_addr = "2001:4860:4860::8888"; // 初始化socket地址结构,避免未定义行为 struct sockaddr_in6 in6_sa{}; in6_sa.sin6_family = AF_INET6; // 转换IPv6地址,增加错误检查 int retval = inet_pton(AF_INET6, presentation_addr, &in6_sa.sin6_addr); if (retval != 1) { std::cout << "inet_pton() 地址转换失败" << std::endl; return 1; } sockaddr *sa = reinterpret_cast<struct sockaddr*>(&in6_sa); char buf[NI_MAXHOST]; // 传递正确的地址结构体长度 retval = getnameinfo(sa, sizeof(in6_sa), buf, sizeof(buf), NULL, 0, NI_NAMEREQD); if (retval) { std::cout << "getnameinfo() 错误码 " << retval << ": " << gai_strerror(retval) << std::endl; } else { std::cout << buf << std::endl; } return 0; }
关键修改说明
- 将
sizeof(sa)替换为sizeof(in6_sa),传递正确的地址结构体长度,让函数能正确解析IPv6地址。 - 用值初始化
struct sockaddr_in6 in6_sa{}清空结构体,避免未初始化内存的干扰。 - 增加
inet_pton的错误检查,确保IPv6地址转换成功后再执行后续逻辑。 - 添加
gai_strerror(retval)输出错误描述,便于调试排查问题。
修复后,代码即可正确解析2001:4860:4860::8888对应的主机名google.com。
内容的提问来源于stack exchange,提问作者Artyom Gevorgyan
相关产品推荐
相关产品推荐

