TCP/IP网络编程学习笔记(六)域名与网络地址

时间:2019-04-15
本文章向大家介绍TCP/IP网络编程学习笔记(六)域名与网络地址,主要包括TCP/IP网络编程学习笔记(六)域名与网络地址使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

一、域名系统

  • DNS,Domain Name System,域名系统,是对IP地址和域名进行相互转换的系统,其核心是DNS服务器
  • 为什么要提供域名?IP地址难记!域名基本不变,IP相对频繁地改变
  • 所有计算机中都记录着默认 DNS 服务器地址,通过这个默认 DNS 服务器得到相应的域名的 IP 地址信息。若该 DNS 服务器无法解析,则会向上级 DNS 服务器询问,逐级上传,最终可能达到顶级 DNS 服务器——根服务器,它知道该向哪个 DNS 服务器询问,向下级 DNS 传递解析请求,得到 IP地址后原路返回,最终将解析的 IP地址传递到发起请求的主机。
  • DNS——分布式数据库管理系统
  • 查看某个域名的 IP地址:ping www.google.com
  • 查看默认 DNS 服务器地址:nslookup(Linux需在执行后再输入server命令)

二、利用域名获取IP地址

1.相关函数

#include<netdb.h>
// 功能:通过域名获取 IP地址等信息
// 返回值:成功时返回 hostent 结构体地址,失败时返回 NULL 指针
struct hostent* gethostbyname(const char* hostname);
struct hostent{
    char* h_name;    // 官方域名
    cahr** h_aliases;    // 主页别名(其他域名,一个主页可以有多个域名,同一IP可以绑定多个域名)
    int h_addrtype;    // 地址族信息(gethostbyname 函数支持 IPv4,IPv6)
    h_length;    // 保存IP地址长度,IPv4地址为 4,IPv6地址为 16
    h_addr_list;    // 以整数形式保存域名对应的所有IP地址(用户较多的网站可能分配多个IP给同一个域名,利用多个服务器进行负载均衡)
}

2.演示程序

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<netdb.h>

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

int main(int argc, char* argv[]) {
    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->h_name);
    for (int 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 (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;
}

三、利用IP地址获取域名

1.相关函数

#include<netdb.h>
// 功能:利用IP地址获取域名相关信息
// 参数:
//    addr--含有 IP地址信息的 in_addr 结构体指针,为了同时传递 IPv4地址以外的信息,声明为 char*
//    len--向第一个参数传递的地址信息的字节数,IPv4为 4,IPv6为 16
//    family--传递地址族信息,IPv4为 AF_INET,IPv6为 AF_INET6
//返回值:成功时返回 hostent 结构体变量的地址,失败时返回 NULL 指针
struct hostent* gethostbyaddr(const char* addr,socklent_t len,int family);

2.演示程序

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<arpa/inet.h>
#include<netdb.h>

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

int main(int argc, char* argv[]) {
    struct hostent* host;
    struct sockaddr_in addr;
    if (argc != 2) {
        printf("Usage: %s <addr> \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 (int 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 (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;
}

参考书籍:《TCP/IP网络编程》尹圣雨 著,金果哲 译