您当前的位置:首页 > 计算机 > 编程开发 > VC/VC++

C/C++ 通过域名获取服务器真实IP地址

时间:03-14来源:作者:点击数:

前言

在实际项目中,使用到Tcp连接服务器端,考虑到服务器端有可能提供的是IP地址,也有可能提供的是域名,所以就研究了一下如何从域名中获取真实的IP地址。


一、gethostbyname

主要使用到了gethostbyname这个函数,先带大家了解一下:

1、头文件和函数原型

#include <netdb.h>
struct hostent *gethostbyname(const char *hostname);

2、作用

用于返回对应于给定主机名的主机信息。

3、返回值

返回值 struct hostent:

/* Description of data base entry for a single host.  */
struct hostent
{
  char *h_name;			/* Official name of host.  */
  char **h_aliases;		/* Alias list.  */
  int h_addrtype;		/* Host address type.  */
  int h_length;			/* Length of address.  */
  char **h_addr_list;		/* List of addresses from name server.  */
#ifdef __USE_MISC
# define	h_addr	h_addr_list[0] /* Address, for backward compatibility.*/
#endif
};

从结构体中可以看到,不止返回IP地址,还返回了一下其他信息,具体含有如下:

h_name:该变量存有官方域名,官方域名代表某一主页,但实际上,一些著名公司的域名并未使用官方域名注册。

h_aliases:可以通过多个域名访问同一主页,同一IP可以绑定多个域名,因此,除官方域名外还可指定其他域名。

h_addrtype:gethostbyname函数不仅支持IPv4,还支持IPv6。因此可以通过此变量获取保存在h_addr_list的IP地址的地址族信息。若是IPv4,则此变量存有AF_INET。

h_length:保存IP地址长度。若是IPv4地址,因为是4个字节,则保存4;若是IPv6,因为是16个字节,故保存16。

h_addr_list:该变量以整数形式保存域名的IP地址。另外,用于访问量较大的网站可能分配多个IP给同一域名,利用多个服务器进行负载均衡,同样可以通过此变量获取IP地址信息。

h_addr:该变量是返回h_addr_list列表中的第一个数据。

二、封装函数获取IP

#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
/**
 * @brief 判断传入的是域名还是ip地址,如果是域名,就通过域名获取ip地址,如果是ip地址不处理,直接返回 
 * @param host : 域名或IP地址
 * @return std::string 获取成功返回IP地址,失败返回空
 */
static std::string _GetServerIP(char *host)
{
    if (host == NULL)
    {
        return std::string();
    }

    struct hostent *pstHostent = NULL;
    if (inet_addr(host) == INADDR_NONE)
    {
        if ((pstHostent = gethostbyname(host)) == NULL)
        {
            return std::string();
        }
        char *ipaddr = inet_ntoa(*(struct in_addr *)pstHostent->h_addr);
        if (ipaddr)
        {
            return std::string(ipaddr);
        }
    }
    else
    {
        return std::string(host);
    }
    return std::string();
}

三、实例

#include <arpa/inet.h>
#include <vector>
int main(int argc, char *argv[])
{

    char host[64] = {0};
    snprintf(host, sizeof(host), "%s", "www.baidu.com");
    std::string ipaddr = _GetServerIP(host);
    printf("ipaddr:%s\n", ipaddr.c_str());
    return 0;
}

运行结果:ipaddr:110.242.68.3

四、总结

封装的函数可以直接拿过来使用,已经验证了。

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门