《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 地址和域名之间的转换
使用域名的必要性
- 用户友好性: 域名通常比IP地址更易于记忆和识别,使用域名可以提高用户体验。
- 可扩展性: 域名允许在不更改程序代码的情况下更换服务器IP地址,这在服务器迁移或扩展时非常有用。
- 负载均衡: 通过域名,可以更容易地实现负载均衡,将请求分发到多个服务器上。
- 安全性: 域名可以与SSL/TLS证书结合使用,提供安全的HTTPS连接,保护数据传输的安全。
- 易于管理: 使用域名可以简化网络配置和维护,因为域名解析和管理通常比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:浏览器得到资源后,渲染网页
相关文章:
《TCP/IP网络编程》学习笔记 | Chapter 8:域名及网络地址
《TCP/IP网络编程》学习笔记 | Chapter 8:域名及网络地址 《TCP/IP网络编程》学习笔记 | Chapter 8:域名及网络地址域名系统什么是域名?DNS 服务器IP 地址和域名之间的转换使用域名的必要性利用域名获取 IP 地址利用 IP 地址获取域名 基于 Wi…...
FastHTML快速入门:调试模式和 URL中的变量
调试模式 FastHTML基于FastAPI友好的装饰器模式来指定URL,并添加了额外功能: main.py from fasthtml.common import * app, rt fast_app() rt("/") def get():return Titled("FastHTML", P("让我们开始吧!"…...
C++高级编程(8)
八、标准IO库 1.输入输出流类 1)非格式化输入输出 2)put #include <iostream> #include <string> using namespace std; int main() {string str "123456789";for (int i str.length() - 1; i > 0; i--) {cout.put(str[i]); //从最后一个字符开…...
AUTOSAR_EXP_ARAComAPI的7章笔记(2)
☞返回总目录 相关总结:服务发现实现策略总结 7.2 服务发现的实现策略 如前面章节所述,ara::com 期望产品供应商实现服务发现的功能。服务发现功能基本上是在 API 级别通过 FindService、OfferService 和 StopOfferService 方法定义的,协议…...
【C++】 C++游戏设计---五子棋小游戏
1. 游戏介绍 一个简单的 C 五子棋小游戏 1.1 游戏规则: 双人轮流输入下入点坐标横竖撇捺先成五子连线者胜同一坐标点不允许重复输入 1.2 初始化与游戏界面 初始化界面 X 输入坐标后 O 输入坐标后 X 先达到胜出条件 2. 源代码 #include <iostream> #i…...
仿RabitMQ 模拟实现消息队列项目开发文档2(个人项目)
项目需求分析 核心概念 现在需要将这个项目梳理清楚了,便于之后的代码实现。项目中具有一个生产消费模型: 其中生产者和消费者的个数是可以灵活改变的,让系统资源更加合理的分配。消息队列的主逻辑和上面的逻辑基本一样,只不过我…...
李佳琦回到巅峰背后,双11成直播电商分水岭
时间倏忽而过,又一年的双11即将宣告结束。 从双11正式开始前的《新所有女生的offer》,到被作为“比价”标杆被其他平台直播间蹭、被与其他渠道品牌比较,再到直播间运营一时手快多发了红包……整个双11周期下来,李佳琦直播间在刷新…...
云计算在教育领域的应用
💓 博客主页:瑕疵的CSDN主页 📝 Gitee主页:瑕疵的gitee主页 ⏩ 文章专栏:《热点资讯》 云计算在教育领域的应用 云计算在教育领域的应用 云计算在教育领域的应用 引言 云计算概述 定义与原理 发展历程 云计算的关键技…...
C语言 | Leetcode C语言题解之第543题二叉树的直径
题目: 题解: typedef struct TreeNode Node;int method (Node* root, int* max) {if (root NULL) return 0;int left method (root->left, max);int right method (root->right, max);*max *max > (left right) ? *max : (left right);…...
6、If、While、For、Switch
6、If、While、For、Switch 一、If 1、if-else if (boolean) {代码块 } else if (boolean) {代码块 } else if (boolean) {代码块 } else { // 默认情况代码块 }关于IDEA单元测试控制台不能输入数据的问题: https://blog.csdn.net/m0_72900498/article/details/…...
萤石设备视频接入平台EasyCVR多品牌摄像机视频平台海康ehome平台(ISUP)接入EasyCVR不在线如何排查?
随着智慧城市和数字化转型的推进,视频监控系统已成为保障公共安全、提升管理效率的重要工具。特别是在大中型项目中,跨区域的网络化视频监控需求日益增长,这要求视频监控管理平台不仅要具备强大的视频资源管理能力,还要能够适应多…...
【多线程】线程池如何知道一个线程的任务已经完成
目录 1. 说明2. 任务的生命周期3. 状态更新4. 线程间的协作5. 内部数据结构6. 回调与通知7. 线程池的关闭与清理 1. 说明 1.线程池通过一系列内部机制来知道一个线程的任务已经完成。2.这些机制主要涉及任务的生命周期管理、状态更新以及线程间的协作。 2. 任务的生命周期 1…...
Transformer介绍(一)
Transformer是一种特殊的神经网络,一种机器学习模型。 谷歌在2017年推出的原版Transformer,论文《Attention Is All You Need》,专注于将一种语言的文本翻译成另一种。 而我们要关注的Transformer变种,即构建ChatGPT等工具的模型…...
[CKS] TLS Secrets创建与挂载
目前的所有题目为2024年10月后更新的最新题库,考试的k8s版本为1.31.1 BackGround 您必须使用存储在TLS Secret中的SSL文件,来保护Web 服务器的安全访问。 Task 在clever-cactus namespace中为名为clever-cactus的现有Deployment创建名为clever-cactu…...
java双向链表解析实现双向链表的创建含代码
双向链表 一.双向链表二.创建MyListCode类实现双向链表创建一.AddFirst创建(头插法)二.AddLast创建(尾叉法)三.size四.remove(指定任意节点的首位删除)五.removeAll(包含任意属性值的所有删除)六.AddIndex(给任意位置添加一个节点…...
【Kafka-go】golang的kafka应用
网络上关于go的Kafka还是比较少的今天就先出一篇入门级别的,之后再看看能能出一个公司业务场景中的消息流。 一、下载github.com/segmentio/kafka-go包 go get github.com/segmentio/kafka-go二、建立kafka连接 正常来说下面的配置host topic partition 应该写在…...
redis:set集合命令,内部编码,使用场景
个人主页 : 个人主页 个人专栏 : 《数据结构》 《C语言》《C》《Linux》《网络》 《redis学习笔记》 文章目录 前言命令SADDSMEMBERSSISMEMBERSCARDSPOPSMOVESREM集合间操作SINTERSINTERSTORESUNIONSUNIONSTORESDIFFSDIFFSTORE 内部编码使用场景总结 前言…...
45期代码随想录算法营总结
代码随想录训练营总结与收获 在为期60天的代码随想录训练营结束后,我感慨良多。这段时间不仅让我在编程技能上有了明显的提升,更让我在学习习惯和时间管理上有了深刻的反思和改变。 报名参加这个训练营对我来说是一个重要的监督机制。之前我总是拖延&a…...
深入理解Java中的instanceof关键字及接口新特性:方法实现的可能性
目录 引言 1. 什么是instanceof关键字? 1.1 语法结构 1.2 instanceof的用法示例 1.3 instanceof的应用场景 2. Java中的接口能包含方法实现吗? 2.1 默认方法(Default Method) 2.2 静态方法(Static Method&…...
【python中如果class没有self会怎行】
python中如果class没有self会怎样TOC 在Python中,self是一个约定俗成的名称,用于表示类的实例。如果没有使用self,会导致以下问题: 1、无法访问实例属性: 在类的方法中,如果没有self,方法将无…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...
Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...
MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用
文章目录 一、背景知识:什么是 B-Tree 和 BTree? B-Tree(平衡多路查找树) BTree(B-Tree 的变种) 二、结构对比:一张图看懂 三、为什么 MySQL InnoDB 选择 BTree? 1. 范围查询更快 2…...
tomcat入门
1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效,稳定,易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...
uniapp 小程序 学习(一)
利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 :开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置,将微信开发者工具放入到Hbuilder中, 打开后出现 如下 bug 解…...
