【专栏试读】前后端交互 |(02)交互的规则、标准:HTTP——② HTTP 三次握手、URI、URL 和 URN

29,290 阅读8分钟
原创:itsOli  @前端一万小时

本文首发于公众号前端一万小时

本文版权归作者所有,未经授权,请勿转载!

本文节选自“语雀”私有付费专栏前端一万小时 | 从零基础到轻松就业

❗️❗️❗️
以下链接为本文最新勘误篇章——《【专栏试读】前后端交互 |(02)交互的规则、标准:HTTP——② HTTP 三次握手、URI、URL 和 URN》



1 HTTP 三次握手

1.1 基本概念

在正式讲解“HTTP 三次握手”之前,我们要弄清一个概念: interaction_02-1.png

在“客户端”和“服务器”之间进行“HTTP 请求”发送和返回的过程中,我们首要的是需要去创建“TCP connection”这个东西!

❗️因为 HTTP 本身是不存在“连接”这个概念的,它只有“请求”和“响应”这两个概念!

而“请求”和“响应”都是“数据包”,“数据包”的传输需要一个“传输的通道”,这个“通道/连接”是在 TCP 里边去创建的。

“TCP 传输通道/连接”创建好了之后,其可以通过某种方式声明让它一直保持在那里。而后,我们的“HTTP 请求”就可以在这个“连接”的基础上去发送了。

当然,既然“连接”创建好之后会一直保持在那里,我们就可以在这个“TCP 连接”上去发送多个“HTTP 请求”。

❓我们为什么要让“TCP 连接”一直保持在那里呢? 答:因为“TCP 连接”有一个“三次握手”的过程,而这个过程会有三次网络消耗。若每连接完一次就关闭一次,必然带来很大的消耗和延迟!

“三次握手”表示在“客户端”和“服务端”之间有三次网络传输,只有三次网络传输完成后,“TCP connection”才会被创建,继而“HTTP 请求”才能被发送。

1.2 “三次握手”时序图

interaction_02-2.png

  • 1️⃣首先,“客户端”发起一个“我要创建一个连接”这样的“数据包请求”给“服务端”:

    • SYN=1 :SYN 是一个“标志位”,表示创建了一个标有 SYN 的数据包
    • Seq=X :同时会带一个 Seq,它等于一个数字,一般 X=1
  • 2️⃣然后,“服务端”接收到1️⃣发来的请求后,它就知道此时有客户需要跟我们建立连接了。“服务端”随即就会开启一个 TCP 的 socket 端口,同时返回给“客户端”一个数据包:

    • SYN=1 :这里的 SYN 也是一个标志位;

    • ACK=X+1 :同时返回一个 ACK 标志位,其值等于1️⃣中“客户端”发过来的 Seq 的值 + 1;

      (❗️二者合用,表示:“服务端”返回了一个标有 SYN/ACK 的数据包给“客户端”。)

    • Seq=Y :同时,“服务端”也要返回一个 Seq,其值等于一个新的数字 Y。

  • 3️⃣最后,当“客户端”拿到2️⃣中“服务端”传递过来的数据后,它就知道了“服务端”已经允许它去创建一个“TCP 连接”了。“客户端”随即返回一个数据包给“服务端”:

    • ACK=Y+1 :ACK 是一个“标志位”,表示“客户端”发送了一个标有 ACK 的数据包给“服务端”,其值等于2️⃣中“服务端”发送过来的 Seq 的值 + 1;
    • Seq=Z :同时,“客户端”还要返回一个 Seq,其值等于一个新的数字。

❓为什么我们需要进行“三次握手”的过程呢?
答:这是为了防止“服务端”这边开启一些无用的“连接”。

我们知道,数据是需要经过光纤、各种中间代理服务器等进行传输,这就势必带来一定的“延时”。如果没有“三次握手”,“客户端”发起的**“创建连接”的请求1️⃣**在到达“服务端”后,“服务端”就会直接创建这个“连接”,并把相关数据返回给“客户端”。

这时,意外出现了:数据传输由于网络的原因,“数据”丢失了!“客户端”这边一直没接收到服务器返回的数据。而同时,“客户端”可能设置了一个“超时时间”——在多少时间内没接收到服务器返回的数据,就把“连接”关闭。而后又去发起新的数据请求。

但是,由于没有“三次握手”,我“服务端”这边也不知道你“客户端”压根就没接收到“数据”,你“客户端”也没给我任何反馈!此时,“服务端”的端口却是一直开着的,被白白浪费了。

所以,“三次握手”主要是为了规避网络传输过程中,由于延时而导致的“服务端”白白开销的问题。

1.3 用 Wireshark 直观说明“三次握手”的过程

以下我会使用一个强大的网络抓包工具 Wireshark 去抓取一些数据包进行说明。

❗️Wireshark 的具体安装的使用,我这里不作赘述,Windows 和 macOS 都有对应的官方安装包。这里先跟着我简单用起来,后边实际工作中需要哪个细节知识点再去深究即可。

首先,在终端输入以下命令行查看本机的 IP 地址(下方图片中红框标注的地方):

ifconfig

//Windows 系统是:
ipconfig 

我这边局域网 IP 是 192.168.8.107interaction_02-3.png

然后,打开安装好的 Wireshark,点击下图红框框住的地方,抓取本机目前 Wi-Fi 下的数据包: interaction_02-4.png

随即,你便可以抓取到很多数据包(软件的左上角红色方块可以停止抓包),我这里挑了其中一个:

  • 57030 表示本机的一个端口;
  • 443 表示“服务端”的一个端口。

interaction_02-5.png

仔细看看每一次握手“数据包”的相关信息,无论是是“标志位”的使用,还是各个“值”的关系,都和我们上边“三次握手”时序图里讲解的一模一样。

2 URI、URL 和 URN

2.1 定义

  • URI:Uniform Resourse Identifier 统一资源标识符
  • URL:Uniform Resourse Location 统一资源定位符
  • URN:Uniform Resource Name 统一资源名称

URL 是使用浏览器等访问 Web 页面的时候需要输入的网页地址,如: http://www.baidu.com

URI 是更通用的资源标识符,它由两个主要的子集构成:

  • URL:通过描述资源的位置来描述资源;
  • URN:通过名字来识别资源,和位置无关(目前使用的不多,了解一下即可)。

2.2 URL 的组成部分

我们常见的 URL 主要由三大部分组成:

  • 方案,也就是我们常说的协议;
  • 服务器位置;
  • 资源路径。

例如: https://www.yuque.com/olizhao/qdywxs

具体来说,通用的 URL 由 9 部分组成:

<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<hash>
  • <scheme> :对于 Web 页面来说,最常用的协议就是 http 和 https;

  • <user>:<password> :user 和 password 现在不常见了,我们不会再在 URL 里明文书写用户名和密码,而是通过登录的方式去作用户的认证;

  • <host> :主机可以是 IP 地址或者域名;

  • <port> :端口号用来区分主机上的进程,方便找到 Web 服务器。

    HTTP 默认端口是 80,可以不写,指提供 HTTP 服务的进程监听在 TCP 80 端口。

    这好比银行的服务大厅有多个窗口,其中有个窗口提供外币兑换服务。为了让客户更便捷地找到窗口,银行总部规定默认情况下,各分行的第 80 个窗口提供外币兑换服务,这样需要兑换服务的客户只要找到任意一家分行,直奔 80 号窗口便是。

    这里各分行地址可理解成 IP 地址,大厅的各个窗口可理解成端口。大厅各个窗口的服务内容可由大厅经理安排,这个经理可理解成服务器管理员。意思是虽然 HTTP 默认端口是 80,管理员也可以改成 81 端口,也可以把 80 端口改成 SSH 等其他服务。

  • <path> :path 是资源的路径,也就是资源存放的位置。不一定和物理路径完全对应,符合 Web 服务器路由约定即可;

  • <params> :params 在一些协议中需要参数来访问资源。参数为“名/值对”,URL 中可以包含多个参数字段,它们相互之间,以及与路径的其余部分之间用分号 ; 分隔。

    如: ftp.prep.ai.mit.edu/pub/gnu;type=d ——参数为 type=d ,其中参数名为 type ,值为 d

  • <query>query 是 GET 请求最常用的传递参数方式。用字符 ? 将其与 URL 的其余部分分隔开来——如 ?a=1&b=2&=3

  • <hash> :hash 也称为片段,设计为标识文档的一部分,很多 MVVM 框架用作了路由功能。

    有些资源类型,比如 HTML,除了资源级以外,还可以进一步划分。

    比如一个带有章节的大型文本文档,URL 允许使用 hash 来表示资源内的一个片段,片段挂在 URL 右边,最前面有一个字符 #

    比如: http://www.baidu.com/tools.html#drills 这个例子中,片段引用了百度服务器上页面 /tools.html 中的一个部分,这部分名字叫 drills


下一篇我们集中讲解一个比较重要内容——HTTP 报文,只有弄懂这个知识点,后续的文章才能更轻松地阅读。

祝好,qdywxs ♥ you!