《TCP/IP网络编程》学习笔记 | Chapter 8:域名及网络地址

《TCP/IP网络编程》学习笔记 | Chapter 8:域名及网络地址

  • 《TCP/IP网络编程》学习笔记 | Chapter 8:域名及网络地址
    • 域名系统
      • 什么是域名?
      • DNS 服务器
      • IP 地址和域名之间的转换
      • 使用域名的必要性
      • 利用域名获取 IP 地址
      • 利用 IP 地址获取域名
    • 基于 Windows 的实现
      • Windows 下的 gethostbyname 函数的示例程序
      • Windows 下的 gethostbyname 函数的示例程序
    • 习题
      • (1)下列关于DNS说法错误的是?
      • (2)阅读如下对话,并说明东秀的解决方案是否可行。这些都是大家可以在大学计算机实验室验证的内容。
      • (3)在浏览器地址栏输入www.orentec.co.kr,并整理出主页显示过程。假设浏览器访问的默认DNS服务器中并没有关于www.orentec.co.kr的IP地址信息。

《TCP/IP网络编程》学习笔记 | Chapter 8:域名及网络地址

域名系统

DNS(Domain Name System,域名系统),是对IP地址和域名进行互相转换的系统,其核心是DNS服务器。

什么是域名?

提供网络服务的服务器端也是通过IP地址区分的,但IP地址难记,因此将容易记、易表述的域名分配并取代IP地址。

DNS 服务器

在浏览器地址栏输入www.baidu.com,或用ping命令获取其IP地址,然后在浏览器地址栏输入IP地址便可访问百度主页,那么通过域名访问和通过IP访问这二者有何区别?

从结果上来看这两者没有区别,都是进去百度网页。实际上,域名是赋予服务器端的虚拟地址,而非实际地址。因此需要将虚拟地址转化为实际地址。

那么,如何将域名转化为IP地址呢?DNS服务器承担此重任,可以向DNS服务器请求转换地址。

所有计算机中都记录着默认DNS服务器地址,就是通过默认DNS服务器得到相应域名的IP地址信息。在浏览器地址栏中输入域名后,浏览器通过默认DNS服务器获取该域名对应的IP地址信息,之后才真正接入该网站。

计算机内置的默认DNS服务器并不知道网络上所有域名的IP地址信息,若该DNS服务器无法解析,则会询问其他DNS服务器并提供给用户,如下图所示:

在这里插入图片描述

上图展示了默认DNS服务器无法解析主机询问的域名IP地址时的应答过程,可以看出,默认DNS服务器收到自己无法解析的请求时,向上级DNS服务器询问,通过这种方式逐级向上传递信息,到达顶级DNS服务器时——根DNS服务器,它知道该向哪个DNS服务器询问。向下级DNS传递解析请求,得到IP地址后原路返回,最终将解析的IP地址传递到发起请求的主机,DNS就是这样层次化管理的一种分布式数据库系统。

IP 地址和域名之间的转换

使用域名的必要性

  1. 用户友好性: 域名通常比IP地址更易于记忆和识别,使用域名可以提高用户体验。
  2. 可扩展性: 域名允许在不更改程序代码的情况下更换服务器IP地址,这在服务器迁移或扩展时非常有用。
  3. 负载均衡: 通过域名,可以更容易地实现负载均衡,将请求分发到多个服务器上。
  4. 安全性: 域名可以与SSL/TLS证书结合使用,提供安全的HTTPS连接,保护数据传输的安全。
  5. 易于管理: 使用域名可以简化网络配置和维护,因为域名解析和管理通常比IP地址更简单。

利用域名获取 IP 地址

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

成功时返回hostent结构体地址,失败时返回NULL指针。

参数:

  • hostname:域名字符串。

hostent结构体定义如下:

struct hostent
{char *hname;        // official namechar **h aliases;   // alias listint h_addrtype;     // host address typeint h_length;       // address lengthchar **h_addr_list; // address list
} 

从上述结构体可以看出,当调用gethostbyname函数时不止返回IP信息,同时还带着其他信息,域名转IP时只需关注h_addr_list。下面简要介绍下上述结构体中的各个成员:

  • 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地址信息。

调用gethostbyname函数后返回的hostent结构体变量结构如下图所示:

在这里插入图片描述

示例程序:

#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;if (argc != 2){printf("Usage : %s <addr>\n", argv[0]);exit(1);}// 使用gethostbyname()函数获取主机信息host = gethostbyname(argv[1]); // argv[1]是命令行输入的主机名或IP地址if (!host){error_handling("gethostbyname() 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");// 打印所有IP地址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;
}void error_handling(char *message)
{fputs(message, stderr);fputc('\n', stderr);exit(1);
}

利用 IP 地址获取域名

#include<netdb.h>struct hostent * gethostbyaddr(const char * addr, socklen_t len, int family);

成功时返回hostent结构体地址,失败时返回NULL指针。

参数:

  • addr:包含IP地址信息的in_addr结构体指针。为了同时传递IPv4地址之外的其他信息,该变量的类型声明未char指针。
  • len:IP地址的长度,对于IPv4地址是4,对于IPv6地址是16。
  • family:地址类型,对于IPv4地址是AF_INET,对于IPv6地址是AF_INET6。

示例程序:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netdb.h>void error_handling(const char *message);int main(int argc, char *argv[])
{int i;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]);// 将IP地址转换为域名host = gethostbyaddr((char *)&addr.sin_addr, sizeof(addr.sin_addr), AF_INET);if (!host)error_handling("gethostbyaddr() 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;
}void error_handling(const char *message)
{fputs(message, stderr);fputc('\n', stderr);exit(1);
}

基于 Windows 的实现

与 Linux 基本一致。

#include<winsock2.h>struct hostent *gethostbyname(const char * name);

成功时返回hostent结构体地址,失败时返回NULL指针。

#include<netdb.h>struct hostent * gethostbyaddr(const char * addr, int len, int type);

成功时返回hostent结构体地址,失败时返回NULL指针。

Windows 下的 gethostbyname 函数的示例程序

#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>void ErrorHanding(char *message);int main(int argc, char *argv[])
{WSADATA wsaData;int i;struct hostent *host;if (argc != 2){printf("Usage : %s <addr>\n", argv[0]);exit(1);}if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)ErrorHanding("WSAStartup() error!");host = gethostbyname(argv[1]);if (!host)ErrorHanding("gethostbyname() 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]));WSACleanup();return 0;
}void ErrorHanding(char *message)
{fputs(message, stderr);fputc('\n', stderr);exit(1);
}

编译:

gcc gethostbyname_win.c -lwsock32 -o gethostbyname

运行结果:

C:\Users\81228\Documents\Program\TCP IP Project\Chapter 8>gethostbyname www.naver.com
Official name : www.naver.com.nheos.com
Aliases 1 : www.naver.com
Address type : AF_INET
IP addr 1 : 223.130.192.248
IP addr 2 : 223.130.200.236
IP addr 3 : 223.130.200.219
IP addr 4 : 223.130.192.247

Windows 下的 gethostbyname 函数的示例程序

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>void ErrorHanding(char *message);int main(int argc, char *argv[])
{WSADATA wsaData;int i;struct hostent *host;struct sockaddr_in addr;if (argc != 2){printf("Usage : %s <addr>\n", argv[0]);exit(1);}if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)ErrorHanding("WSAStartup() error!");memset(&addr, 0, sizeof(addr));addr.sin_addr.s_addr = inet_addr(argv[1]);host = gethostbyaddr((char *)&addr.sin_addr, sizeof(addr.sin_addr), AF_INET);if (!host)ErrorHanding("gethostbyaddr() 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]));WSACleanup();return 0;
}void ErrorHanding(char *message)
{fputs(message, stderr);fputc('\n', stderr);exit(1);
}

编译:

gcc gethostbyaddr_win.c -lwsock32 -o gethostbyaddr

运行结果:

C:\Users\81228\Documents\Program\TCP IP Project\Chapter 8>ping www.bilibili.com正在 Ping a.w.bilicdn1.com [59.36.228.21] 具有 32 字节的数据:
来自 59.36.228.21 的回复: 字节=32 时间=8ms TTL=55
来自 59.36.228.21 的回复: 字节=32 时间=12ms TTL=55
来自 59.36.228.21 的回复: 字节=32 时间=104ms TTL=55
来自 59.36.228.21 的回复: 字节=32 时间=11ms TTL=5559.36.228.21 的 Ping 统计信息:数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):最短 = 8ms,最长 = 104ms,平均 = 33msC:\Users\81228\Documents\Program\TCP IP Project\Chapter 8>gethostbyaddr 59.36.228.21
Official name : 21.228.36.59.broad.jm.gd.dynamic.163data.com.cn
Address type : AF_INET
IP addr 1 : 59.36.228.21

习题

(1)下列关于DNS说法错误的是?

a. 因为DNS存在,故可以用域名替代IP。
b. DNS服务器实际上是路由器,因为路由器根据域名决定数据路径。
c. 所有域名信息并非集中于一台DNS服务器,但可以获取某一DNS服务器中未注册的IP地址。
d. DNS服务器根据操作系统进行区分,Windows下的DNS服务器和Linux下的DNS服务器是不同的。

答:b、d。

(2)阅读如下对话,并说明东秀的解决方案是否可行。这些都是大家可以在大学计算机实验室验证的内容。

静洙:“东秀吗?我们学校网络中使用的默认DNS服务器发生了故障,无法访问我要投简历的公司主页!有没有办法解决?”

东秀:“网络连接正常,但DNS服务器发生了故障?”

静洙:“恩!有没有解决方法?是不是要去周围的网吧?”

东秀:“有那必要吗?我把我们学校的DNS服务器IP地址告诉你,你改一下你的默认DNS服务器地址。”

静洙:“这样可以吗?默认DNS服务器必须连接到本地网络吧!”

东秀:“不是!上次我们学校DNS服务器发生故障时,网管就给了我们其他DNS服务器的I地址呢。”

静洙:“那是因为你们学校有多台DNS服务器!”

东秀:“是吗?你的话好像也有道理。那你快去网吧吧!”

答:如果网络上没有特别的限制,可以将与本地网络相连的DNS服务器指定为其他完好的DNS服务器。因此,东秀提议的方法可能成为解决方法。也就是说,静洙可以不去网吧。

(3)在浏览器地址栏输入www.orentec.co.kr,并整理出主页显示过程。假设浏览器访问的默认DNS服务器中并没有关于www.orentec.co.kr的IP地址信息。

步骤1:计算机向默认DNS服务器询问IP地址
步骤2:默认DNS服务器没有IP地址信息,因此向DNS主机发出询问
步骤3:DNS查询服务器向更上级的DNS服务器查询
步骤4:DNS查询服务器将查到的域名对应的IP地址逐级返还给主机
步骤5:网络浏览器根据该IP访问对应的网站
步骤6:计算机与网站服务器建立HTTP连接,浏览器得到HTML等资源
步骤7:浏览器得到资源后,渲染网页

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/11241.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Liunx:简易版进程池

进程向系统申请资源存在一定的效率问题。系统调用在底层是有成本的。频繁的向操作系统申请资源会造成一定的开销。解决办法是一次性向系统申请你需要的资源&#xff0c;将这些资源在用户层管理维护起来&#xff0c;减少程序频繁的陷入内核。这就是池化的意思&#xff0c;可以简…

百亿AI数字人社会初现:Project Sid展示智能代理文明进化路径

项目背景 Project Sid 是一项开创性的AI代理人文明实验,旨在通过新开发的认知架构 PIANO 探讨AI代理人是否能够在大规模数字社会中实现文明的演进。这项实验不仅展示了社会进步、角色分化、治理体系及文化传播等特征,还揭示了一个包含百亿“数字人类”的社会可能性。 PIANO…

CoCa: Contrastive Captioners are Image-Text Foundation Models

Jiahui Yu† Zirui Wang†{jiahuiyu, ziruiw}google.comVijay Vasudevan Legg Yeung Mojtaba Seyedhosseini Yonghui WuGoogle Research 参考代码链接&#xff1a;https://github.com/lucidrains/CoCa-pytorch 模型效果对比网址&#xff1a;CoCa: Contrastive Captioners are …

HarmonyOS一次开发多端部署三巨头之功能级一多开发和工程级一多开发

功能级一多开发与工程级一多开发 引言功能级一多开发SysCaps机制介绍能力集canlUse接口 工程级一多开发三层架构规范 引言 一次开发多端部署 定义&#xff1a;一套代码工程&#xff0c;一次开发上架&#xff0c;多端按需部署 目标&#xff1a;支撑开发者快速高效的开发多终端设…

c中的文件管理

大家好&#xff0c;今天我们来看看语言中的文件管理&#xff0c;聊到这个&#xff0c;我们就得先说说文件的特点。 1.文件是一种让数据持久化的方法&#xff0c;使用文件可以将数据直接存放在电脑的硬盘上&#xff0c;做到数据持久化。 那么什么是文件呢&#xff1f; 硬盘上…

ElasticSearch的Python Client测试

一、Python环境准备 1、下载Python安装包并安装 https://www.python.org/ftp/python/3.13.0/python-3.13.0-amd64.exe 2、安装 SDK 参考ES官方文档: https://www.elastic.co/guide/en/elasticsearch/client/index.html python -m pip install elasticsearch一、Client 代…

python中常见的8种数据结构之一数组的应用

在Python中&#xff0c;数组是一种常见的数据结构&#xff0c;用于存储一系列相同类型的元素。在实际应用中&#xff0c;数组可以用于解决各种问题。 以下是数组在Python中的一些常见应用&#xff1a; 1. 存储和访问数据&#xff1a;数组可以用于存储和访问一组数据。可以通过…

Android 实现柱形图

在 Android 中实现柱状图&#xff0c;可以使用流行的图表库 MPAndroidChart&#xff0c;它支持多种类型的图表&#xff0c;包括柱状图、折线图、饼图等。下面是一个基本的柱状图实现步骤&#xff0c;具体分为以下几个部分&#xff1a; 1. 添加依赖 首先&#xff0c;你需要在 …

python基础

1.python的第一个程序 2.代码注释 3.交互模式 4.变量与常量 电影文件是有文件类型&#xff1a;MP4&#xff0c;avi 图片文件&#xff1a;jpeg&#xff0c;png&#xff0c;jpg 5.数据类型 python类型决定了当前变量在内存中的存储体积 字符串&#xff0c;字符&a…

13.UE5流星火雨,引导施法技能制作

2-15 流星火雨&#xff0c;引导施法技能制作、随机数_哔哩哔哩_bilibili 目录 1.为流星火雨添加按键映射 2.创建流星火雨的动画蒙太奇 3.实现播放动画蒙太奇的逻辑 ​编辑 4.定义发射一波流星火雨的发射物 5.使用动画通知释放流星火雨 1.为流星火雨添加按键映射 创建名为流…

【python程序】恢复曾经删除的QQ说说

是否还能想起曾经的QQ说说&#xff0c;是否还想知道自己以前删除了什么 今天就给大家介绍下这个可以恢复以前删除的QQ说说的 小工具 这个工具是由python编写的&#xff0c;也已经打包好了小程序&#xff0c;一键运行 具体下载地址&#xff1a;https://pan.quark.cn/s/b3f41e3…

Springboot 整合 Java DL4J 打造企业知识图谱构建系统

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/literature?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;…

goroutine 介绍

引子&#xff1a; 线程比如打开腾讯视频然后开始下载多个视频&#xff0c;下载任务就是线程 但是这并不是同时进行的&#xff0c;只是时间片比较短切换的比较快 进程和线程的关系 有些程序可以多进程有些可能不支持 并发和并行 并发和并行的根本区别是&#xff1a;并发在同一时…

Ubuntu[无桌面]——修改Docker镜像源文件

下载镜像的时候&#xff0c;一般有两种方式&#xff1a; &#xff08;1&#xff09;在宿主主机配置相应的文件/etc/docker/daemon.json&#xff0c;配置镜像源环境地址 &#xff08;2&#xff09;进入https://quay.io/search中&#xff0c;输入搜索需要下载的镜像名称&#xff…

Linux开发讲课49--- Linux 启动过程分析

理解运转良好的系统对于处理不可避免的故障是最好的准备。 启动过程非常简单。内核在单核上以单线程和同步状态启动&#xff0c;似乎可以理解。但内核本身是如何启动的呢&#xff1f;initrd&#xff08;initial ramdisk&#xff09; 和引导程序(bootloader)具有哪些功能&#…

简单安全的密码生成器PSWD

在我们折腾的过程中&#xff0c;经常要生成 APP KEY、JWT_SECRET、SECRET_KEY 一类的参数&#xff0c;除了可以用 openssl rand 命令来生成外&#xff0c;也可以用在线的密码生成器来生成&#xff0c;例如我们今天介绍的 PSWD 什么是 PSWD ? PSWD 是一个简单且安全的密码生成…

【cursor添加azure】在cursor中添加azure的openai api

右上角-设置 会弹出 下拉找到azure 这部分从你的azure后台获取 返回cuesor&#xff0c;点击 输入你的模型名称 然后回车 就可以开始使用了&#xff5e;

JSqlParser、JavaCC实操

1. 背景 项目中使用mubatis-plus&#xff0c;有个sql报错&#xff0c;信息如下 通过debug我发现是第四行代码报错 net.sf.jsqlparser.parser.CCJSqlParserUtil#parseStatements public static Statements parseStatements(String sqls) throws JSQLParserException {CCJSqlP…

【人工智能训练师】3 集群搭建

开启集群环境 本次环境为单节点伪集群环境&#xff0c;环境中已经安装JDK1.8、Hadoop2.7.7、Mysql5.7、hive2.3.4。— 1.环境中已经安装/root/software/hadoop-2.7.7&#xff0c;格式化HDFS&#xff0c;开启集群&#xff0c;查看集群状态。&#xff08;HDFS端口为9000&#x…

力扣二叉树题解含思路(C++实现)

1.求二叉树的最近公共祖先&#xff1a; 原题链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 假设这题的p&#xff0c;q分别为7和8&#xff0c;而它们的最近公共祖先肯定是为3。 这题我们大致的思路为保存p&#xff0c;q的绝对路径&#xff0c;接着通过存储的绝对路…