C/C++ obtains the real IP address of the server through domain name

Table of Contents of Series Articles



Insert image description here

Preface

In actual projects, Tcp is used to connect to the server. Considering that the server may provide an IP address or a domain name, we studied how to obtain the real IP address from the domain name.


1. gethostbyname

The gethostbyname function is mainly used . Let me take you through it first:

1. Header files and function prototypes

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

2. Function

Used to return the host information corresponding to the given host name.

3. Return value

Return value 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
};

As can be seen from the structure, it not only returns the IP address, but also returns other information, which is as follows: h_name
: This variable stores the official domain name. The official domain name represents a certain homepage, but in fact, the domain names of some famous companies do not Not registered with an official domain name.
h_aliases : The same homepage can be accessed through multiple domain names, and the same IP can be bound to multiple domain names. Therefore, in addition to the official domain name, other domain names can be specified.
h_addrtype : The gethostbyname function not only supports IPv4, but also supports IPv6. Therefore, the address family information of the IP address saved in h_addr_list can be obtained through this variable. If it is IPv4, this variable contains AF_INET.
h_length : Save the IP address length. If it is an IPv4 address, because it is 4 bytes, 4 is saved; if it is IPv6, because it is 16 bytes, 16 is saved.
h_addr_list : This variable stores the IP address of the domain name in the form of an integer. In addition, websites with a large number of visits may allocate multiple IPs to the same domain name and use multiple servers for load balancing. You can also obtain IP address information through this variable.
h_addr : This variable is the first data in the returned h_addr_list list.

2. Encapsulation function to obtain 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();
}

3. Example

#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;
}

Running result: ipaddr:110.242.68.3

4. Summary

The encapsulated function can be used directly and has been verified.

Guess you like

Origin blog.csdn.net/weixin_37926485/article/details/127665234