《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.rhkb.cn/news/470825.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端开发中常用的包管理器(npm、yarn、pnpm、bower、parcel)

文章目录 1. npm (Node Package Manager)2. Yarn (Yarn Package Manager)3. pnpm4. Bower5. Parcel总结 前端开发中常用的包管理器主要有以下几个&#xff1a; 1. npm (Node Package Manager) 简介&#xff1a; npm 是 Node.js 的默认包管理器&#xff0c;也是最广泛使用的包…

HarmonyOS 如何实现传输中的数据加密

文章目录 摘要引言数据传输加密概述选择加密算法和传输协议加密实现方案与 Demo 代码配置 HTTPS/TLSAES 加密的实现代码详解RSA加密的实现代码详解 QA环节总结参考资料 摘要 本文将介绍在 HarmonyOS 应用中如何实现数据传输的加密策略。我们将讨论常见的加密算法&#xff08;如…

ArkTs简单入门案例:简单的图片切换应用界面

在鸿蒙 OS 应用开发的过程中&#xff0c;我们常常需要通过组合各种组件和编写相应的逻辑来实现丰富多样的功能。今天&#xff0c;我就来和大家详细解析一段实现简单图片切换功能的代码&#xff0c;希望能帮助到那些刚接触鸿蒙 OS 应用开发的朋友们。 一、代码导入部分 Entry …

influxDB 时序数据库安装 flux语法 restful接口 nodjsAPI

安装 Install InfluxDB | InfluxDB OSS v2 Documentation Debian和Ubuntu用户可以用apt-get包管理来安装最新版本的InfluxDB。 对于Ubuntu用户&#xff0c;可以用下面的命令添加InfluxDB的仓库&#xff0c;添加之后即可apt-get 安装influxdb2 wget -q https://repos.influx…

丹摩征文活动|丹摩智算平台使用指南

目录 1. 登录平台与工作环境设置1.1 访问与登录1.2 创建或选择项目1.3 初始化项目环境 2. 数据上传与管理2.1 数据上传2.2 数据管理与预处理2.3 数据可视化 3. 模型构建与训练3.1 模型选择3.2 参数配置3.3 模型训练与评估 4. 模型部署与应用4.1 模型部署4.2 接口调用与集成4.3 …

NAT网络工作原理和NAT类型

NAT基本工作流程 通常情况下&#xff0c;某个局域网中&#xff0c;只有路由器的ip是公网的&#xff0c;局域网中的设备都是内网ip&#xff0c;内网ip不具备直接与外部应用通信的能力。 处于内网的设备如何借助NAT来实现访问外网的应用&#xff1f; 对于开启了NAT功能的局域网…

LLMs 如何处理相互矛盾的指令?指令遵循优先级实验

编者按&#xff1a;想象一下&#xff0c;你正在开发一个 AI 助手&#xff0c;突然发现 system message 和用户提示词存在冲突&#xff0c;这时 AI 会听谁的&#xff1f;这种情况不仅困扰着开发者&#xff0c;还可能导致 AI 系统的不稳定和不可预测&#xff0c;影响用户体验和系…

qt QProcess详解

1、概述 QProcess是Qt框架提供的一个类&#xff0c;它用于在应用程序中执行外部进程。QProcess提供了一系列函数来启动、控制和与外部进程进行交互&#xff0c;使得开发者能够在自己的应用程序中集成和调用其他程序或服务。这个类在需要执行系统命令、启动其他应用程序或进行文…

Appium配置2024.11.12

百度得知&#xff1a;谷歌从安卓9之后不再提供真机layout inspector查看&#xff0c;仅用于支持ide编写的app调试用 所以最新版android studio的android sdk目录下已经没有了布局查看工具... windows x64操作系统 小米k30 pro手机 安卓手机 Android 12 第一步&#xff1a…

《ElementPlus 与 ElementUI 差异集合》Icon 图标 More 差异说明

参考 《element plus 使用 icon 图标(两种方式)》使用 icon 升级 Vue2 升级 Vue3 项目时&#xff0c;遇到命名时的实心与空心点差异&#xff01; ElementUI&#xff1a; 实心是 el-icon-more空心是 el-icon-more-outline ElementPlus&#xff1a; 实心是 el-icon-more-fill…

WebSocket和HTTP协议的性能比较与选择

WebSocket和HTTP协议的性能比较与选择 引言&#xff1a; 在web应用开发中&#xff0c;无论是实时聊天应用、多人在线游戏还是实时数据传输&#xff0c;网络连接的稳定性和传输效率都是关键要素之一。目前&#xff0c;WebSocket和HTTP是两种常用的网络传输协议&#xff0c;它们…

【数据结构与算法】第11课—数据结构之选择排序和交换排序

文章目录 1. 选择排序1.1 直接选择排序1.2 堆排序 2. 交换排序2.1 冒泡排序2.2 快速排序(找基准值法1----Hoare版本)2.2.1 特殊场景12.2.2 特殊场景22.2.3 代码2.2.4 快速排序的时间复杂度 2.3 快速排序(找基准值法2---挖坑法)2.3.1 特殊情况1处理2.3.2 特殊情况2处理 2.4 快速…

MySQL技巧之跨服务器数据查询:进阶篇-从A数据库复制到B数据库的表中

MySQL技巧之跨服务器数据查询&#xff1a;进阶篇-从A数据库复制到B数据库的表中 基础篇已经描述&#xff1a;借用微软的SQL Server ODBC 即可实现MySQL跨服务器间的数据查询。 而且还介绍了如何获得一个在MS SQL Server 可以连接指定实例的MySQL数据库的连接名: MY_ODBC_MYSQ…

UVC 输出视频格式修改和windows下数据分析

文章目录 前言一、UVC MJPEG视频帧描述符1.MJPG视频帧格式示例 二、UVC YUV2、NV12、M420、I420无压缩视频帧描述符GUID1.如YUV2数据参数初始为: 三、UVC Windows下UVC摄像头数据分析总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 项目需要&#…

大数据开发面试宝典

312个问题&#xff0c;问题涵盖广、从自我介绍到大厂实战、19大主题&#xff0c;一网打尽、真正提高面试成功率 一、Linux 1. 说⼀下linux的常⽤命令&#xff1f; 说一些高级命令即可 systemctl 设置系统参数 如&#xff1a;systemctl stop firewalld关闭防火墙 tail / hea…

更改Ubuntu22.04锁屏壁纸

更改Ubuntu22.04锁屏壁纸 sudo apt install gnome-shell-extensions gnome-shell-extension-manager安装Gnome Shell 扩展管理器后&#xff0c;打开“扩展管理器”并使用搜索栏找到“锁屏背景”扩展

GxtWaitCursor:Qt下基于RAII的鼠标等待光标类

有时我们需要以阻塞的方式执行一点耗时的操作&#xff0c;这时需要主窗口光标呈现忙状态&#xff0c;GxtWaitCursor正是为此设计&#xff1b;重载的构造函数&#xff0c;可以让光标呈现忙状态一定时间后自动恢复。 GxtWaitCursor.h #pragma once#include <QObject>// // …

Unity3D实现视频和模型融合效果

系列文章目录 unity工具 文章目录 系列文章目录👉前言👉一、效果展示如下👉二、VideoPlayer播放视频(一)👉2-1、Hieraechy面板右键创建videoPlayer👉2-2、Assets面板右键创建RenderTexture👉2-3、把设置好的RenderTexture拖到videoPlayer里面还有本地视频视频�…

探索Pillow库:Python图像处理的瑞士军刀

文章目录 **探索Pillow库&#xff1a;Python图像处理的瑞士军刀**1. 背景&#xff1a;为何选择Pillow&#xff1f;2. Pillow是什么&#xff1f;3. 如何安装Pillow&#xff1f;4. 五个简单的库函数使用方法4.1 打开图像4.2 显示图像4.3 转换图像格式4.4 调整图像大小4.5 旋转图像…

HelloMeme 上手即用教程

HelloMeme是一个集成空间编织注意力的扩散模型&#xff0c;用于生成高保真图像和视频。它提供了一个代码库&#xff0c;包含实验代码和预训练模型&#xff0c;支持PyTorch和FFmpeg。用户可以通过简单的命令行操作来生成图像和视频。 本文将详细介绍&#xff0c;如何在GPU算力租…