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


    系列文章目录



    在这里插入图片描述

    前言

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


    一、gethostbyname

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

    1、头文件和函数原型

    #include 
    struct hostent *gethostbyname(const char *hostname);
    
    • 1
    • 2

    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
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    从结构体中可以看到,不止返回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 
    #include 
    #include 
    #include 
    #include 
    #include 
    /**
     * @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();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    三、实例

    #include 
    #include 
    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    运行结果:ipaddr:110.242.68.3

    四、总结

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

  • 相关阅读:
    机器学习总结四:逻辑回归与反欺诈检测案例
    力扣 1582. 二进制矩阵中的特殊位置
    第3关:Client连接及状态
    神经网络的数学基础资料,神经网络的数学理论
    使用VuePress快速搭建博客
    什么是多域名证书?
    java spring cloud 工程企业管理软件-综合型项目管理软件-工程系统源码
    java boot项目读取yml配置信息
    【学习QT必备的C++基础】C++继承、派生与多态
    Maven 知识点总结
  • 原文地址:https://blog.csdn.net/weixin_37926485/article/details/127665234