TCP/IP Network Programming Chapter 8: Domain Name and Network Address

domain name system

Here is a brief introduction to the domain name system for computer network novice, as we usually use domain names similar to www.baidu.com when surfing the Internet. That is to say, we can access a website through the IP address and the domain name at the same time, so what is the difference between the two? In fact, it can be understood that the domain name is the virtual address of the IP address, not the actual address. Therefore, it is necessary to convert the virtual address into a real address. The important task of this conversion is to the DNS server.

Each computer has a default DNS server. If the computer wants to query the IP address corresponding to a certain domain name, it will first send a query request to the default DNS server. If the DNS server does not know the IP address corresponding to a certain domain name, it will query the upper-level DNS server. Once it reaches the top DNS server it definitely knows which DNS to make the request to. Then, the resolution request is passed to the lower-level DNS, and the original path is recursively returned after obtaining the IP address. Finally, the computer can know the IP address of the target domain name.

Is it necessary to use a domain name in the program?

This question answers the reason we study this chapter. Imagine a scenario where we are developing a client for a company to use the services provided by the company. So if you want to use the company's services, you must visit the company's server. So is the server domain name or server address stored inside the client? It is not easy to maintain the IP address when the system is running, and various reasons related to the system will cause the IP address to change. Then due to the change, we need to modify the IP address in the source code all the time, which is unrealistic for a user without professional knowledge.

Once a domain name is registered, it may be permanent, so it is better to use the domain name to write programs. In this way, when running the program, the IP address is obtained according to the domain name, and then connected to the server, so that the program will not depend on the server IP address. Therefore, the conversion function between IP address and domain name is also needed in the program.

Obtaining an IP address using a domain name

The following function can be used to obtain the IP address by passing the domain name in string format.

#include<netdb.h>
struct hostnet * gethostbyname(const char*hostname);
//成功时返回houstnet结构体地址,失败时返回NULL指针

First introduce the following structure definition:

struct hostent{
    char * h_name;        //official name
    char ** h_aliases;    //alias list
    int h_addrtype;       //host address type
    int h_length;         //address length
    char ** h_addr _list; //address list
}

h_name
This variable contains the official domain name (Official domain name). The official domain name represents a certain home page, but in fact,
the domain names of some well-known companies are not registered with the official domain name.

h_aliases
can access the same home page through multiple domain names. Multiple domain names can be bound to the same IP, so
other domain names can be specified in addition to the official domain name. This information can be obtained through h_aliases.

The h_addrtype
gethostbyname function not only supports IPv4, but also supports IPv6. Therefore, the address family information of the IP address stored in h_addr_list can be obtained through this variable. If IPv4, this variable holds AF_INET.

h_length
saves the length of the IP address. If it is an IPv4 address, since it is 4 bytes, save 4; for IPv6, because it is 16 bytes, save 16.

h_addr_list

This is the most important member. Use this variable to save the IP address corresponding to the domain name in integer form. In addition, websites with many users may assign multiple IPs to the same domain name and use multiple servers for load balancing. At this time, the address information can also be obtained through this variable.

Here is an example to demonstrate:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<netdb.h>
void error_handling(char* message);

int main(int argc,char*argv[]){
    int i;
    struct hostent *host;
    if(argc!=2){
       printf("Usage : %s <addr>\n",argv[0]);
       exit(1);
    }

    host=gethostbyname(argv[1]);
    if(!host)error_handling("gethost...error");

    printf("Official name: %s \n",host->name);
    for(int i=0;host->h_aliases[i];i++)printf("Aliases %d: %s\n",i+1,host->aliases[i]);
    printf("Address type: %s\n",(host->h_addrtype==AF_INET)?"AF_INET":"AF_INET6");
    for(int i=0;host->h_addr_list[i];i++)
       printf("IP addr %d: %s \n",i+1,inet_ntoa(*(struct in_addr*)host->h_addr_list[i]));
    return 0;
}

voie error_handling(char *message){
    fputs(message,stderr);
    fputc('\n',stderr);
    exit(1);
}

Now discuss lines 26-28 of the above example. If you only look at the definition of the hostent structure, the structure member h_addr_list points to an array of string pointers. However, the elements in the string pointer array actually point to the address value of the in_addr structure variable instead of the string.

Obtain domain name using IP address

#include<netdb.h>
struct hostent *gethostbyaddr(const char* addr,socklen_t len,int family);
//成功时返回hostent结构体变量地址,失败时返回NULL指针
        addr    //含有IP地址信息的in_addr结构体指针。为了同时传递IPv4地址以外的其他信息,该变量声明为char指针
        len     //第一个参数传递的地址信息的字节数
        family  //传递的地址族信息

The following example demonstrates how to use this function:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netdb.h>
void error_handling(char *message);

int main(int argc, char *argv[]){
    int i;
    struct hostent *host;
    struct sockaddr_in addr;

    if(argc!=2){
       printf("Usage : %s <IP>\n", argv[0]);
       exit(1);
    }

    memset(&addr, 0, sizeof(addr));
    addr.sin_addr.s_addr=inet_addr(argv[1]);

    host=gethostbyaddr((char*)&addr.sin_addr,4, AF_INET);
    if(!host)error handling("gethost... error");

    printf("Official name: %s \n", host->h_name);
    for(i=0; host->h_aliases[i]; i++)printf("Aliases %d: %s \n", i+1, host->h_aliases[i]);
    printf("Address type: %s \n",(host->h_addrtype==AF_INET)?"AF_INET":"AF_INET6");
    for(i=0; host->h_addr_list[i]; i++)
    printf("IP addr %d: %s \n",i+1,inet_ntoa(*(struct in_addr*)host->h_addr_list[i]));
 
    return 0;
}

voie error_handling(char*message){
    fputs(message,stderr);
    fputc('\n',stderr);
    exit(1);
}

Windows-based implementation

There is also a function of the same name with a similar function in the Windows platform. First introduce the gethostbyname function.

#include<winsock2.h>
struct hostent* gethostbyname(const char *name);
//成功返回hostent结构体变量地址值,失败时返回NULL指针

The function name, parameter and return type are the same as those in Linux, introduce the next function

#include<winsock2.h>
struct hostent* gethostbyaddr(const char* addr,int len,int family);
//成功时返回hostent结构体变量地址,失败时返回NULL指针

The above functions are also completely consistent with the functions in Linux.

Guess you like

Origin blog.csdn.net/Reol99999/article/details/131719779