【问题标题】:why getnameinfo() retrieve repeated address?为什么 getnameinfo() 检索重复的地址?
【发布时间】:2020-06-07 22:18:03
【问题描述】:

我正在使用 BSD 套接字 API 中的 getnameinfo() 函数从主机获取地址,我想获取所有可用的地址:

 struct addrinfo hints;
  memset(&hints, 0, sizeof(hints));
  hints.ai_flags = AI_ALL;
  struct addrinfo *peer_address;
  if (getaddrinfo(argv[1], NULL, &hints, &peer_address)) {
    fprintf(stderr, "getaddrinfo() ERROR.\n");
    return EXIT_FAILURE;
  }

  printf("Remote address(es):\n");
  struct addrinfo *address = peer_address;

  while((address = address->ai_next)) {
    char address_buffer[100];
    getnameinfo(address->ai_addr, address->ai_addrlen,
        address_buffer, sizeof(address_buffer), 0, 0, NI_NUMERICHOST);
    printf("\t> %s\n", address_buffer);
  }

  freeaddrinfo(peer_address);

构建并运行这段代码,我得到了输出:

$lookup google.com
Remote address(es):
   > 172.217.203.100
   > 172.217.203.100
   > 172.217.203.102
   > 172.217.203.102
   > 172.217.203.102
     .
     .
     .
   > 2607:f8b0:400c:c07::8a
   > 2607:f8b0:400c:c07::8a
   > 2607:f8b0:400c:c07::8a

为什么每个 IP 地址都要打印两三次?

【问题讨论】:

  • 它没有检查getnameinfo() 的结果,所以有些可能会失败,留下前一个条目的值。另外,这不是跳过列表中的 first 条目吗?
  • getnameinfo() 很好,返回0,没有问题,但是谢谢,我必须记住检查每个函数的返回值。

标签: c sockets networking


【解决方案1】:

您会看到过度未指定的 hints 变量的影响,这通常会将列表缩小到您所要求的范围内。

当您询问所有内容时,似乎对于每个 IP 地址,都有一个 tcp (SOCK_STREAM)、udp (SOCK_DGRAM) 以及 IP (SOCK_RAW) 条目,但在只是查找 IP 地址——而不是服务——我看不出这有什么用。

解决此问题的简单方法是更新您的提示:

    struct addrinfo hints;
    memset(&hints, 0, sizeof hints);
    hints.ai_flags = AI_ALL;
    hints.ai_socktype = SOCK_RAW;   // ADD ME

此外,您的循环确实会跳过第一个条目,因此可以替换为:

    for (struct addrinfo *address = peer_address
       ;  address != 0
       ;  address = address->ai_next )
    {
        // do stuff

一个有用的参考:What's the "hints" mean for the addrinfo name in socket programming

【讨论】:

  • 感谢史蒂夫,现在一切都非常清楚了,我可能会注意到,如果我从地址打印服务/端口,顺便说一下,只需要指定套接字类型就可以了。
  • 嗯,这个答案未被接受 - 它不再正确吗?
  • 是的,是正确的,只是我的错误,被接受了,非常感谢史蒂夫!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-10
  • 1970-01-01
  • 2016-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多