从浏览器输入网址到网页显示内容——浏览器到协议栈

在这里插入图片描述

思维导图

在这里插入图片描述

生成HTTP请求信息

在浏览器输入网址

网址

  • 即URL(Uniform Resource Locator,统一资源定位符),它除了“http:”, 网址还可以以其他一些文字开头, 例如“ftp:”“file:”“mailto:” C 等。

  • 例如在访问 Web 服务器和 FTP 服务器时, URL 中会包含服务器的域名 E 和要访问的文件的路径名等,
    而发邮件的 URL 则包含收件人的邮件地址。 此外, 根据需要, URL 中还会包含用户名、 密码、服务器端口号 A 等信息。

为什么有各种URL

  • 浏览器是一个具备多种客户端功能的综合性客户端软件
    • 使用浏览器来访问Web 服务器
    • 在FTPD 服务器上下载和上传文件
    • 同时也具备电子邮件客户端的功能
  • 因此它需要一些东西来判断应该使用其中哪种功能来访问相应的数据, 而各种不同的URL 就是用来干这个的, 比如访问 Web 服务器时用“http:”, 而访问 FTP服务器时用“ftp:”

在这里插入图片描述

浏览器解析 URL

对URL的各个元素进行拆分,

  • 图 1.2( b) 中的 URL 表示要访问 www.lab.glasscom.com 这个 Web 服务器上路径名为 /dir/file1.html 的文件, 也就是位于 /dir/ 目录 D 下的 file1.html 这个文件
    在这里插入图片描述

省略文件名的情况

  • http://www.lab.glasscom.com/dir/
  • http://www.lab.glasscom.com/
  • http://www.lab.glasscom.com
  • 我们会在服务器上事先设置好文件名省略时要访问的默认文件名。 这个设置根据服务器不同而不同, 大多数情况下是 index.html 或者 default.htm 之类的文件名。 因此, 像前面这样省略文件名时, 服务器就会访问 /dir/index.html或者 /dir/default.htm。

HTTP协议

地位

  • 解析完 URL 之后, 我们就知道应该要访问的目标在哪里了。 接下来,浏览器会使用 HTTP 协议来访问 Web 服务器

作用

  • HTTP 协议定义了客户端和服务器之间交互的消息内容和步骤
    在这里插入图片描述

生成HTTP请求消息

首先, 客户端会向服务器发送请求消息。 请求消息中包含的内容是“对什么” 和“进行怎样的操作” 两个部分。

  • 其中相当于“对什么” 的部分称为 URI(Uniform Resource Identifier,统一资源标识符)。 一般来说, URI 的内容是一个存放网页数据的文件名或者是一个 CGI 程序 的文件名, 例如“ /dir1/file1.html” “/dir1/program1.cgi” 等 C。 不过, URI 不仅限于此, 也可以直接使用“http:”开头的 URLD 来作为 URI。 换句话说就是, 这里可以写各种访问目标, 而这些访问目标统称为 URI
  • 相当于接下来“进行怎样的操作” 的部分称为方法方法表示需要让Web 服务器完成怎样的工作, 其中典型的例子包括读取 URI 表示的数据、将客户端输入的数据发送给 URI 表示的程序等。 表 1.1 列举了主要的方法,通过这张表大家应该能够理解通过方法可以执行怎样的操作
方法介绍

在这里插入图片描述GET方法

  • 最常用的
  • 一般当我们访问 Web 服务器获取网页数据时, 使用的就是 GET 方法。 所谓一般的访问过程大概就是这样的: 首先, 在请求消息中写上 GET 方法,然后在 URI 中写上存放网页数据的文件名“/dir1/file1.html”, 这就表示我们需要获取 /dir1/file1.html 文件中的数据。 当 Web 服务器收到消息后, 会打开 /dir1/file1.html 文件并读取出里面的数据, 然后将读出的数据存放到响应消息中, 并返回给客户端。 最后, 客户端浏览器会收到这些数据并显示在屏幕上

POST

  • 经常使用
  • 我们在表单 A 中填写数据并将其发送给 Web 服务器时就会使用这个方法。 当我们在网上商城填写收货地址和姓名, 或者是在网上填写问卷时, 都会遇到带有输入框的网页, 而这些可以输入信息的部分就是表单。 使用 POST 方法时, URI 会指向 Web 服务器中运行的一个应用程序的文件名, 典型的例子包括“index.cgi”“index.php” 等。 然后, 在请求消息中, 除了方法和 URI 之外, 还要加上传递给应用程序和脚本的数据。 这里的数据也就是用户在输入框里填写的信息。当服务器收到消息后, Web 服务器会将请求消息中的数据发送给 URI 指定的应用程序。 最后, Web 服务器从应用程序接收输出的结果, 会将它存放到响应消息中并返回给客户端
请求消息格式

在这里插入图片描述消息头

  • 存放额外的详细信息
  • 消息头的规格中定义了很多项目, 如日期、 客户端支持的数据类型、 语言、 压缩格式、 客户端和服务器的软件名称和版本、 数据有效期和最后更新时间等。 这些项目表示的都是非常细节的信息。
在浏览器格式

在这里插入图片描述

发送请求后会收到响应

响应消息

  • 收到请求消息之后, Web 服务器会对其中的内容进行解析, 通过 URI和方法来判断“对什么”“进行怎样的操作”, 并根据这些要求来完成自己的工作, 然后将结果存放在响应消息中。
  • 在响应消息的开头有一个状态码,它用来表示操作的执行结果是成功还是发生了错误。 当我们访问 Web 服务器时, 遇到找不到的文件就会显示出 404 Not Found 的错误信息, 其实这就是状态码。 状态码后面就是头字段和网页数据。 响应消息会被发送回客户端, 客户端收到之后, 浏览器会从消息中读出所需的数据并显示在屏幕上。 到这里,HTTP 的整个工作就完成了

网页内容包含图片时

  • 如果网页的内容只有文字, 那么到这里就全部处理完毕了
    当网页中包含图片时, 会在网页中的相应位置嵌入表示图片文件的标签的控制信息。 浏览器会在显示文字时搜索相应的标签, 当遇到图片相关的标签时, 会在屏幕上留出用来显示图片的空间, 然后再次访问 Web 服务器, 按照标签中指定的文件名向 Web 服务器请求获取相应的图片并显示在预留的空间中。 这个步骤和获取网页文件时一样, 只要在 URI 部分写上图片的文件名并生成和发送请求消息就可以了

  • 由于每条请求消息中只能写 1 个 URI, 所以每次只能获取 1 个文件,如果需要获取多个文件, 必须对每个文件单独发送 1 条请求。 比如 1 个网页中包含 3 张图片, 那么获取网页加上获取图片, 一共需要向 Web 服务器发送 4 条请求。

  • 判断所需的文件, 然后获取这些文件并显示在屏幕上, 这一系列工作的整体指挥也是浏览器的任务之一, 而 Web 服务器却毫不知情。 Web 服务器完全不关心这 4 条请求获取的文件到底是 1 个网页上的还是不同网页上的, 它的任务就是对每一条单独的请求返回 1 条响应而已

响应消息格式

在这里插入图片描述除了第一行外,与请求消息功能相同

  • 第一行的内容为状态码和响应短语, 用来表示请求的执行结果是成功还是出错。 状态码和响应短语表示的内容一致, 但它们的用途不同。 状态码是一个数字, 它主要用来向程序告知执行的结果( 表1.3); 相对地, 响应短语则是一段文字, 用来向人们告知执行的结果

一个完整实例

这是一个浏览器与 Web 服务器之间交互消息的实例。在这个例子中, 我们需要获取一张名为 sample1.htm 的网页, 网页中包含一张名为 picture.jpg 的图片
在这里插入图片描述在这里插入图片描述在这里插入图片描述
在这里插入图片描述

向 DNS 服务器查询 Web 服务器的 IP 地址

IP地址

HTTP消息如何发送给Web服务器

  • 生成 HTTP 消息之后, 接下来我们需要委托操作系统将消息发送给Web 服务器。 尽管浏览器能够解析网址并生成 HTTP 消息, 但它本身并不具备将消息发送到网络中的功能, 因此这一功能需要委托操作系统来实现
  • 在委托操作系统发送消息时, 必须要提供的不是通信对象的域名, 而是它的 IP 地址。 因此, 在生成 HTTP 消息之后, 下一个步骤就是根据域名查询 IP 地址

数据包传输过程

  • 凡是通过集线器连接起来的所有设备都属于同一个子网
  • 发送者发出的消息首先经过子网中的集线器 , 转发到距离发送者最近的路由器上( 图 1.8 ①)。 接下来,路由器会根据消息的目的地判断下一个路由器的位置, 然后将消息发送到下一个路由器, 即消息再次经过子网内的集线器被转发到下一个路由器( 图 1.8 ②)。 前面的过程不断重复, 最终消息就被传送到了目的地

在这里插入图片描述

DNS

由来

  • 因为人们难以记住IP地址,而路由器使用名称运行效率低,故采用让人来使用名称, 让路由器来使用 IP 地址的运行方案
  • 为了填补两者之间的障碍, 需要有一个机制能够通过名称来查询 IP 地址, 或者通过 IP 地址来查询名称, 这样就能够在人和机器双方都不做出牺牲的前提下完美地解决问题。 这个机制就是 DNS
查询IP过程
  • 查询 IP 地址的方法非常简单, 只要询问最近的 DNS 服务器“www.lab.glasscom.com 的 IP 地址是什么” 就可以了, DNS 服务器会回答说“该服务器的 IP 地址为 xxx.xxx.xxx.xxx”。
DNS服务器与域
  • 在教材中为了简化,认为一台 DNS 服务器中只存放一个域的信息,实际上,由于一台 DNS 服务器可以存放多个域的信息,因此并不是每个域名都有一台与之相对应的 DNS 服务器。比如网络运营商的 DNS 服务器中就存放了很多个域的信息

根域的 DNS 服务器

  • 根域的 DNS 服务器信息保存在互联网中所有的 DNS 服务器中。 这样一来, 任何 DNS 服务器就都可以找到并访问根域 DNS 服务器了。 因此, 客户端只要能够找到任意一台DNS 服务器, 就可以通过它找到根域 DNS 服务器, 然后再一路顺藤摸瓜找到位于下层的某台目标 DNS 服务器

如何在每台DNS服务器保留根服务器信息

  • 分配给根域 DNS 服务器的 IP 地址在全世界仅有 13 个 , 而且这些地址几乎不发生变化, 因此将这些地址保存在所有的 DNS 服务器中也并不是一件难事。 实际上, 根域DNS 服务器的相关信息已经包含在 DNS 服务器程序的配置文件中了, 因此只要安装了 DNS 服务器程序, 这些信息也就被自动配置好了

根域服务器只有13个,中国怎么办

  • 根域 DNS 服务器在运营上使用多台服务器来对应一个 IP 地址,因此尽管IP 地址只有 13 个,但其实服务器的数量是很多的。在我国有26个根域名服务器节点。
  • https://zhuanlan.zhihu.com/p/107492241

找目标DNS服务器过程
在这里插入图片描述在这里插入图片描述

通过缓存加快 DNS 服务器的响应
  • 有时候并不需要从最上级的根域开始查找, 因为 DNS 服务器有一个缓存功能, 可以记住之前查询过的域名。 如果要查询的域名和相关信息已经在缓存中, 那么就可以直接返回响应, 接下来的查询可以从缓存的位置开始向下进行
  • DNS服务器中保存的信息都设置有一个有效期,当缓存中的信息超过有效期后, 数据就会从缓存中删除。

通过解析器向 DNS 服务器发出查询

解析器

  • 向 DNS 服务器发出查询, 也就是向 DNS 服务器发送查询消息, 并接收服务器返回的响应消息。 换句话说, 对于 DNS 服务器, 我们的计算机上一定有相应的 DNS 客户端, 而相当于 DNS 客户端的部分称为 DNS 解析器, 或者简称解析器
  • 解析器实际上是一段程序, 它包含在操作系统的 Socket 库中

Socket 库提供查询 IP 地址的功能

  • Socket 库也是一种库, 其中包含的程序组件可以让其他的应用程序调用操作系统的网络功能 A, 而解析器就是这个库中的其中一种程序组件

查询过程

  • 调用解析器后, 解析器会向 DNS 服务器发送查询消息, 然后 DNS 服务器会返回响应消息。 响应消息中包含查询到的 IP 地址, 解析器会取出 IP地址, 并将其写入浏览器指定的内存地址中

Socket内部实现
在这里插入图片描述
在这里插入图片描述
DNS服务器的IP地址

  • 向 DNS 服务器发送消息时, 我们当然也需要知道 DNS 服务器的 IP 地址。 只不过这个 IP 地址是作为 TCP/IP 的一个设置项目事先设置好的, 不需要再去查询了

委托协议栈发送消息

知道了 IP 地址之后, 就可以委托操作系统内部的协议栈向这个目标 IP地址发送消息了。向操作系统内部的协议栈发出委托时,需要按照指定的顺序来调用 Socket 库中的程序组件。

过程

  • 简单来说, 收发数据的两台计算机之间连接了一条数据通道, 数据沿着这条通道流动, 最终到达目的地在进行收发数据操作之前, 双方需要先建立起这条管道才行。 建立管道的关键在于管道两端的数据出入口, 这些出入口称为套接字。 我们需要先创建套接字, 然后再将套接字连接起来形成管道。 实际的过程是下面这样的。 首先, 服务器一方先创建套接字然后等待客户端向该套接字连接管道。当服务器进入等待状态时, 客户端就可以连接管道了。 具体来说, 客户端也会先创建一个套接字, 然后从该套接字延伸出管道, 最后管道连接到服务器端的套接字上。当双方的套接字连接起来之后, 通信准备就完成了。 接下来, 就像我们刚刚讲过的一样, 只要将数据送入套接字就可以收发数据了。

我们再来看一看收发数据操作结束时的情形。 当数据全部发送完毕之后, 连接的管道将会被断开。 管道在连接时是由客户端发起的, 但在断开时可以由客户端或服务器任意一方发起 。 其中一方断开后,另一方也会随之断开, 当管道断开后, 套接字也会被删除。 到此为止, 通信操作就结束了

在这里插入图片描述
收发数据操作
在这里插入图片描述

创建套接字阶段

客户端创建套接字的操作非常简单, 只要调用 Socket 库中的 socket 程序组件就可以了。套接字创建完成后, 协议栈会返回一个描述符, 应用程序会将收到的描述符存放在内存中

描述符

  • 描述符是用来识别不同的套接字的, 大家可以作如下理解,计算机中会进行多个数据的通信操作,所以可能存在多个套接字,在这样的情况下, 我们就需要一种方法来识别出某个特定的套接字, 这种方法就是描述符

连接阶段:把管道接上去

接下来, 我们需要委托协议栈将客户端创建的套接字与服务器那边的套接字连接起来。应用程序通过调用 Socket 库中的名为 connect 的程序组件来完成这一操作。

当调用 connect 时, 需要指定描述符、服务器 IP 地址和端口号这 3 个参数

描述符

  • 描述符是和委托创建套接字的应用程序进行交互时使用的, 并不是用来告诉网络连接的另一方的, 因此另一方并不知道这个描述符。是用来在一台计算机内部识别套接字的机制

服务器 IP 地址

  • IP 地址不是分配给每一台设备的,而是分配给设备中安装的网络硬件的。因此,如果一台设备中安装了多个网络硬件,那么就会有多个IP 地址

端口号

  • 端口号就是用来让通信的另一方能够识别出套接字的机制
  • 客户端
    • 只要指定了事先规定好的端口号, 就可以连接到相应的服务器程序的套接字。
    • 服务器端口号的规则是全球统一的,为了避免重复和冲突,端口号和 IP 地址一样都是由 IANA这一组织来统一管理的。
  • 服务器
    • 那么服务器也得知道客户端的套接字号码才行吧, 这个问题是怎么解决的呢? 事情是这样的, 首先, 客户端在创建套接字时, 协议栈会为这个套接字随便分配一个端口号 。 接下来, 当协议栈执行连接操作时, 会将这个随便分配的端口号通知给服务器

当调用 connect 时, 协议栈就会执行连接操作。 当连接成功后, 协议栈会将对方的 IP 地址和端口号等信息保存在套接字中, 这样我们就可以开始收发数据了

通信阶段:传递消息

当套接字连接起来之后, 剩下的事情就简单了。 只要将数据送入套接字, 数据就会被发送到对方的套接字中。应用程序无法直接控制套接字, 因此还是要通过 Socket 库委托协议栈来完成这个操作。 这个操作需要使用 write 这个程序组件

当消息返回后, 需要执行的是接收消息的操作。 接收消息的操作是通过 Socket 库中的 read 程序组件委托协议栈来完成的。read将消息放在接收缓冲区,接收缓冲区是一块位于应用程序内部的内存空间

断开阶段:收发数据结束

调用 Socket 库的 close 程序组件进入断开阶段,连接在套接字之间的管道会被断开, 套接字本身也会被删除。

Web 服务器会首先调用close 来断开连接。 断开操作传达到客户端之后, 客户端的套接字也会进入断开阶段

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王蒟蒻

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值