You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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;
}

关键修改说明

  1. 将sizeof(sa)替换为sizeof(in6_sa),传递正确的地址结构体长度,让函数能正确解析IPv6地址。
  2. 用值初始化struct sockaddr_in6 in6_sa{}清空结构体,避免未初始化内存的干扰。
  3. 增加inet_pton的错误检查,确保IPv6地址转换成功后再执行后续逻辑。
  4. 添加gai_strerror(retval)输出错误描述,便于调试排查问题。

修复后,代码即可正确解析2001:4860:4860::8888对应的主机名google.com。

内容的提问来源于stack exchange,提问作者Artyom Gevorgyan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 13:02:23