【问题标题】:Resolve ip to hostname将ip解析为主机名
【发布时间】:2012-05-12 14:18:14
【问题描述】:

我正在尝试从 IP 地址解析主机名。我曾尝试使用gethostbyaddr()getnameinfo(),但在许多情况下,主机名根本无法解析。有没有更好的方法将 IP 地址转换为有效的主机名?

char* ip = argv[1];
// using gethostbyaddr()
hostent * phe = gethostbyaddr(ip, strlen(ip), AF_INET);
if(phe) {
  cout << phe->h_name << "\n";
}

// using getnameinfo()
char hostname[260];
char service[260];
sockaddr_in address;
memset(&address, 0, sizeof(address));
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr(ip);
int response = getnameinfo((sockaddr*)&address, 
                            sizeof(address), 
                            hostname, 
                            260, 
                            service, 
                            260, 
                            0);
if(response == 0) {
  cout << hostname << "\n";
}

【问题讨论】:

  • 并非所有 IP 地址都有反向主机名。是什么让您认为不返回主机名的 IP 地址应该有一个?
  • @Bruno - 在某些情况下,当我没有获得主机名时,我尝试从终端运行 nslookup &lt;address&gt;,并且该命令确实返回了主机名。所以我在想也许有更准确的方法来做这种事情。
  • 我知道这不是一个答案,但您应该坚持使用 getaddrinfo 和 getnameinfo,因为它们在 Ipv4 和 Ipv6 网络地址的两种情况下都很有用。
  • gethostbyaddr() char*作为第一个参数!

标签: c++ c sockets


【解决方案1】:

我尝试过使用gethostbyaddr()getnameinfo() [...]。有没有更好的方法将 IP 地址转换为有效的主机名?

不,getnameinfo() 是首选方法。


您可以检查getnameinfo()EAI_AGAIN 的结果,如果相等则重试请求。


同时收到EAI_OVERFLOW 并不意味着您没有收到回复。无论如何,当您提供 259 个字符来放置结果时,您很可能不会得到 EAI_OVERFLOW... ;-)


顺便说一句:excanoe 是正确的 his comment 坚持使用 getaddrinfo()getnameinfo() ... - gethostbyaddr()gethostbyname() 以某种方式被弃用了。处理它们的结果也很复杂,并且容易引发编程错误。

【讨论】:

    【解决方案2】:

    我使用的是 Windows 很抱歉(如果你使用 *nix,你可以跳过 WSADATA 部分)关于这个版本:)

      #include <stdio.h>
      #include <stdlib.h>
      #include <stdint.h>
    
      #include <winsock2.h>
    
      int main(){
        struct addrinfo    hints;
        struct addrinfo   *res=0;
        int       status;
    
        WSADATA   wsadata;
        int statuswsadata;
        if((statuswsadata=WSAStartup(MAKEWORD(2,2),&wsadata))!=0){
          printf("WSAStartup failed: %d\n",statuswsadata);
        }
    
        hints.ai_family   =AF_INET;
    
        status=getaddrinfo("87.250.251.11",0,0,&res);
    
        {
          char host[512],port[128];
    
          status=getnameinfo(res->ai_addr,res->ai_addrlen,host,512,0,0,0);
    
          printf("Host: %s",host);
    
          freeaddrinfo(res);
        }
      }
    

    我明白了:

    d:\temp\stack>ip
    Host: yandex.ru
    

    87.250.251.11是主机yandex.ru的网络地址:

    C:\Users\user>ping yandex.ru
    
    Pinging yandex.ru [87.250.251.11] with 32 bytes of data:
    Reply from 87.250.251.11: bytes=32 time=21ms TTL=56
    Reply from 87.250.251.11: bytes=32 time=21ms TTL=56
    Reply from 87.250.251.11: bytes=32 time=21ms TTL=56
    
    Ping statistics for 87.250.251.11:
        Packets: Sent = 3, Received = 3, Lost = 0 (0% loss),
    Approximate round trip times in milli-seconds:
        Minimum = 21ms, Maximum = 21ms, Average = 21ms
    

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-12
      • 2011-05-07
      • 2019-09-29
      • 1970-01-01
      • 1970-01-01
      • 2013-11-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多