c - 为什么getnameinfo()检索重复的地址?

标签 c sockets networking

我使用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地址都打印两次或三遍?

最佳答案

您会看到一个过度指定的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

关于c - 为什么getnameinfo()检索重复的地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62252397/

相关文章:

java - 如何确定哪个网络。接口(interface)与java一起使用

c - 在 C 程序中使用 telnet

c++ - 在每第 n 次出现时反转字符串

复杂的通用堆栈

c++ - 防止使用 glibc 头文件

Python,建立独占的TCP连接

c - 如何在套接字编程c中从telnet客户端读取服务器上的参数

android - 如何在Android中读取套接字输入流

linux - 可以将 AF_INET 套接字连接到 AF_UNIX 吗?

c - x86-64 中的内存分配