关于http:一文串联-HTTPTCPIP以太网

38次阅读

共计 5218 个字符,预计需要花费 14 分钟才能阅读完成。

最近部门组织了一次前端性能优化交流会,大家从输出页面 URL 到最终页面展现内容这个过程提出了许多优化点。但同时发现很多同学对 HTTP 协定层的常识不能串联起来,于是整顿了这篇文章,心愿能够给大家带来一丝灵感。

当咱们在页面上发动一个 AJAX 申请的时候,在网络协议层面都经验了哪些内容?

// 发动申请
fetch('https://baidu.com')
// 协定层 1...
// 协定层 2...
// 协定层 3...
.then(res=>
  // 失去后果
  console.log(res)
})

如上述代码所示,咱们对 baidu.com 发动了一个网络申请,最终在 then 办法中失去了具体的响应内容。

应用 Wireshark 抓包后果如下:

图中能够看到,申请 baidu.com 时,首先通过 TCP 3 次握手建设连贯,而后通过 HTTP 传输内容,最初通过 TCP 4 次挥手断开连接。

实在的过程更加简单,咱们次要剖析以下几点:

  • 建设连贯阶段

    • DNS 域名解析(应用层)
    • 建设 TCP 连贯(传输层)

      • 通过 IP 寻址找到指标服务器(网络层)
      • 通过 Mac 寻址找到服务器硬件接口(数据链路层)
      • 通过网线向服务器硬件接口传输比特信息(物理层)
  • 发送数据阶段

    • 建设 SSL 平安连贯(应用层)
    • 发送 HTTP 申请(应用层)

建设连贯阶段

要获取 baidu.com 的网页内容,就须要和 baidu 服务器建设连贯,怎么建设这个连贯呢?

  1. 通过 DNS 获取 baidu 的 IP 地址。
  2. 建设 TCP 连贯。

DNS 域名解析

通过 DNS 解析,咱们就能找到 baidu 服务器对应的 IP 地址。

如图:

通过 DNS 解析后,咱们就能失去 baidu.com 的 IP 地址了:39.156.69.79 和 220.181.38.148,通常客户端会随机选中一个 IP 地址进行通信。

域名的解析步骤

其实 IP 不肯定要通过 DNS 解析能力获取,它通常会被客户端缓存,只有在 DNS 缓存都没有命中的时候才会申请 DNS 服务器。

判断步骤如下:

  1. 判断浏览器是否有缓存 IP 地址。
  2. 判断本机是否有缓存该 IP 地址,如:查看 Host 文件。
  3. 判断本地域名解析服务器是否有缓存 IP 地址,如:电信,联通等运营商。
  4. 向 DNS 根域名解析服务器,解析域名 IP 地址。
  5. 向 DNS 二根域名解析服务器,解析域名 IP 地址。
  6. 以此类推,最终取得 IP 地址。

建设 TCP 连贯

有了 IP 地址之后,客户端和服务器端就能建设连贯了,首先是建设 TCP 连贯。

TCP 是一种面向连贯的、牢靠的 、基于 字节流 的传输层通信协议。

在这一层,咱们传输的数据会依照一个个的字节装入报文中,当报文的长度达到最大分段(MSS)时,就会发送这个报文。如果传输的报文很长,可能会被拆分成多个 TCP 报文进行传输。

TCP 报文头如下:

咱们次要看以下几点:

  • 源端口、目标端口。
  • 序列号:seq,报文的惟一标识。
  • 确认号:ack,报文的确认标识,便于确认 seq 是否曾经收到。
  • TCP 标记:

    • SYN 为 1 示意这是连贯申请或是连贯承受申请。用于创立连贯和同步序列号。
    • ACK 为 1 示意确认号字段无效。留神这里大写的 ACK 只是一个标记,和确认号 ack 并不相同。
    • FIN 为 1 示意要求开释连贯。
  • 窗口:示意发送方能够接管的字节数,即接管窗口大小,用于流量管制。

接下来,咱们看一下 TCP 是怎么建设连贯的?

如图所示,建设 TCP 连贯须要 3 个步骤,俗称三次握手。

  • 第一次握手:客户端向服务器端发送序列号 seq=x 的标识,示意开始建设连贯。
  • 第二次握手:服务器端回发一个 ack=x+1 的标识,示意确认收到第一次握手,同时发送本人的标识 seq=y。

    • 客户端确认本人收回的数据可能被服务器端收到。
  • 第三次握手:客户端发送 ack=y+1 的标识,标识确认收到第二次握手。

    • 服务器端确认本人收回的数据可能被客户端收到。

通过了 3 次握手,即保障了客户端和服务器端都能失常发送和接收数据,TCP 连贯也就建设胜利了。

TCP 牢靠传输原理

上文中说到,TCP 是牢靠的传输,这是为什么呢?

这是因为 TCP 外部应用了 进行期待协定 ARQ,它通过 确认 重传 机制,实现了信息的牢靠传输。

例如:

  • 客户端发送数据 M1
  • 服务器端确认数据 M1 收到
  • 客户端发送数据 M2
  • 服务器端确认数据 M2 收到
  • 顺次类推 …

在这期间,如果某一条数据很久都没有失去确认,客户端就会重传这条数据。这样一来,对于与每一次发送的数据,服务器端都失去了确认,即保障了数据的可靠性。

尽管 ARQ 能够满足数据可靠性,但每次只能发送和确认一个申请,效率太低了,于是就产生了间断 ARQ 协定。

间断 ARQ 协定 会间断发送一组数据,而后再批量期待这一组数据的确认信息,好比把单线程 ARQ 变成了多线程,大大提高了资源的利用效率。

如:

  • 客户端发送数据 M1、M2、M3、M4。
  • 服务器端确认数据 M4 收到,示意 M4 及之前的数据都收到了。
  • 客户端发送数据 M5、M6、M7、M8。
  • 服务器端确认数据 M8 收到,示意 M8 及之前的数据都收到了。

在这个流程中,服务器端不须要对每一个数据都返回确认信息,而是接管到多个数据时一并确认,这个形式叫做 累计确认


这里有个疑难,TCP 的每一次握手,是怎么找到目标服务器呢?

答:通过 IP 协定。

依据 IP 协定找到指标服务器

IP 协定的目标是实现网络层的数据转发,它通过路由器一直跳转,最终把数据胜利送达目的地。

上文中的每一次 TCP 握手以及数据交互,都是通过 IP 协定去传输的。

IP 报文头如下:

咱们关注以下两点就能够了:

  • 源 IP 地址
  • 目标 IP 地址

发动一个 IP 申请执行流程如下:

  1. 构建 IP 申请头(源 IP、指标 IP)。
  2. IP 协定通过算法,计算出一条通往服务器端的门路。
  3. 发送端查问路由表,找出下一跳的 IP 地址(通常是路由器),并发送数据。
  4. 路由器查问路由表,找出下一跳的 IP 地址,并发送数据。
  5. 一直反复步骤 4,直到找到目标局域网。
  6. 发送数据。

路由表存在于计算机或路由器中,由目标 IP 地址、子网掩码、下一跳地址、发送接口四局部组成。通过目标 IP 地址,即可找到下一跳的地址,进行转发。

例如:A 要向 G 发送 IP 数据。

具体流程如下:

  • A 生成 IP 头部(源 IP:A,目标 IP:G)

    • A 查问路由表,发现下一跳为 B,于是把数据传给 B。
  • B 生成 IP 头部(源 IP:A,目标 IP:G)

    • B 查问路由表,发现下一跳为 E,于是把数据传给 E。
  • E 生成 IP 头部(源 IP:A,目标 IP:G)

    • E 查问路由表,发现下一跳为 G,于是把数据传给 G。
  • 达到目的地 G。

你是否有纳闷,为什么 IP 会依照这条门路向 G 传输数据呢?

其实,上图中的门路并非只有一条,咱们通过 ABEG 达到了目的地 G,同样也能够通过 ABCFHG 达到 G,这两种门路都能实现工作,为什么 IP 不抉择 ABCFHG 这条门路呢?

这就波及到了 IP 寻址的算法。

IP 寻址算法

咱们能够把网络中的所有计算机都看做是一个点,计算机之间的连贯看做是一条线,这些点和线就组合成了一个图。

例如:

通过上图,咱们就把简单的网络转化成了数学问题。IP 寻址算法,其实就是图论中的最短门路的算法。

最短门路算法在 IP 协定中有 2 种实现:

  • RIP 协定

    • 应用间隔矢量算法,确保 IP 路由跳转的次数最小
    • 原理

      • 每个节点中都保留有其余节点的地位信息(跳数和下一跳的 IP)。
      • 通过和街坊节点进行数据交换,更新本人到目的地的最短距离,一直反复,即可失去终点到起点的最短门路。
      • 实现简略,开销很小,实用于小型网络。
  • OSPF 协定

    • 应用迪杰斯特拉算法,确保 IP 路由跳转的速度最快
    • 原理

      • 从起始点开始,采纳贪婪算法的策略,每次遍历到始点间隔最近且未拜访过的顶点的邻接节点,直到扩大到起点为止。
      • 实用于大型网络。

通过以上两个协定,咱们就能找到通往目的地的门路了。


这里抛出一个问题:IP 数据是怎么从一个路由器跳到另一个路由器呢?

答:通过以太网协定。

通过 Mac 寻址找到服务器硬件接口

IP 协定次要是用来寻找最优门路的,具体的传输是由以太网协定来做的。

以太网属于数据链路层,它次要负责相邻设施的通信。原理是通过查问交换机 Mac 表,找到通信单方的物理接口,进而开始通信。

以太网报文头如下:

咱们只用关怀以下 3 个点:

  • 源 Mac 地址
  • 目标 Mac 地址
  • 校验码 CRC:校验以后帧是否无效。

能够看到,以太网层都是通过 Mac 地址进行通信的,这里的 Mac 地址是哪里来的呢?

答:通过 ARP 协定。

ARP 协定 是一个通过解析 IP 地址来找寻 Mac 地址的协定。IP 地址转换成 Mac 地址后,就能进行以太网数据传输了。

例如:

当机器 A 向机器 C 发送数据时:

  • A 构建以太网报文(源地址:A,目标地址:C),并通过网卡收回数据帧。
  • 数据帧达到交换机 B,交换机取出目标地址 C 的 Mac 地址。
  • B 查问 Mac 表,依据目的地 Mac 地址,匹配 C 的硬件接口。

    • 如果找到 C 的硬件接口,发送数据。
    • 如果未找到 C 的硬件接口,向 B 直连的所有机器发送播送信息找 C,找到后会把 C 记录到 Mac 表中。

通过上述的流程,咱们就找到了目标机器的硬件接口。


通过以太网协定,咱们找到了指标机器的硬件接口,接下来要怎么发送信息呢?

答:通过物理层。

通过网线向服务器硬件接口传输比特信息

在没有 WiFi 的年代,咱们只能通过插网线来进行上网,网线其实就是物理层的设施之一。

网线能够由多种资料组成,最常见的就是光纤和电缆。

光纤和电缆的传输原理相似,都是通过两个信号来模仿二进制数据的,一个信号即为一个比特。

  • 电缆中:高电位示意 1,低点位示意 0。
  • 光纤中:光洁示意 1,光燃烧示意 0。

如:在光纤中,咱们通过观察光的闪动,即可得悉传输的二进制数据。

有了这些物理设施,咱们就能把简单的数据转换成光信号或者电信号进行传输了。

发送数据阶段

发送数据能够分为两个步骤:

  • 建设平安层 SSL
  • 发送 HTTP 申请

建设平安层 SSL

本文的案例是发送一个 HTTPS 的申请,所以在发送数据之前,会创立一个 SSL 平安层,用于数据加密。

通常的加密办法有两种:

  • 非对称加密

    • A 有钥匙,B 没有钥匙,且他们都有一个公共的锁,B 给 A 发送数据时,都会先把数据锁起来再发送。
    • 接收数据时,A 用钥匙解开锁,即可失去数据。除 A 以外,其他人没有钥匙,也就获取不到数据。
    • 实现了单向通信加密。
  • 对称加密

    • A、B 单方都有一把雷同的钥匙和一个公共的锁,每次发送数据时,都把数据放在锁里进行发送。
    • 接收数据时,A、B 单方就用各自的钥匙来解锁。其他人没有钥匙,也就获取不到数据。
    • 实现了双向通信加密。

互联网通信是双向的,所以咱们须要应用对称加密,可是,怎样才能保障通信单方都有一把雷同的钥匙呢?

目前的解决方案:

  • 先应用非对称加密,进行秘钥协商,让通信单方拿到雷同的钥匙。
  • 而后应用对称加密,进行加密传输。

秘钥协商过程如图:

图中划重点:

  1. 客户端发送本身反对的加密算法。
  2. 服务器端抉择一种加密算法,同时返回数字证书。
  3. 客户端确认证书无效。
  4. 客户端生成随机数,并应用证书中的服务器公钥加密,而后发送给服务器。
  5. 服务器端应用私钥解密,取得随机数。
  6. 单方应用第 2 步确定的加密算法,把随机数进行加密,即可取得雷同的对称加密秘钥。

Ok,秘钥协商之后,咱们的 SSL 平安层也就建好了。

秘钥协商时存在一个问题:

秘钥协商时,怎么保障是和真正的服务器在协商,而不是一个中间人呢?

答:数字证书

数字证书重点关注 2 个局部:

  • 服务器公钥
  • 数字签名

其中,数字签名又是由服务器公钥和证书私钥加密生成的,目标是为了避免服务器公钥被篡改。

有了数字证书,客户端就能通过验证证书,来判断服务器是否是真正的服务器了。

验证逻辑如下:

能够看到,数字证书通过同样的算法进行解密,如果失去雷同的信息摘要,就能保证数据是无效的,如果不统一,则会验证失败,回绝后续的申请。

到这里为止,所有的筹备工作都就绪了,接下来才是发送 HTTP 申请。

发送 HTTP 申请

HTTP 协定其实就是制订了一个通信规定,规定了客户端和服务器之间的通信格局。

以申请 baidu 首页为例:

如上图所示,发动 HTTP 申请时,必须恪守以下规定:

  • 申请办法(必填)GET
  • 申请地址(必填)/
  • HTTP 协定版本(必填)1.1
  • 其余 HTTP 头部字段(可选)HostUser-AgentAccept
  • 申请参数,放在空行前面(可选)

服务器响应申请时,同样恪守了 HTTP 响应规定:

  • HTTP 协定版本(必填)1.1
  • 响应状态码(必填)200
  • 状态码形容(必填)OK
  • 其余 HTTP 头部字段(可选)DateServerETagLast-Modified
  • 申请参数,放在空行前面(可选)

只有咱们恪守这个规定,就能进行 HTTP 通信了。

到目前为止,咱们曾经剖析实现了数据申请的所有过程,你是否都了解了呢?

思考与总结

本文通过一个网络申请,对整个 HTTP、TCP、IP、以太网等协定进行了流程化剖析,最初再梳理一下:

  1. 申请 baidu.com。
  2. DNS 解析 baidu.com,失去 IP 地址。
  3. 建设 TCP 连贯。
  4. IP 协定通过算法,计算出一条通往服务器最优门路。
  5. IP 沿着门路跳转时,会通过 ARP 协定把 IP 地址转换成 Mac 地址。
  6. 以太网通过 Mac 地址,找到通信单方的硬件接口。
  7. 物理层通过网线作为载体,在两个硬件接口之间传输比特信号。
  8. TCP 连贯建设结束。
  9. 建设 SSL 平安层。
  10. 发送 HTTP 申请。

最初,如果你对此有任何想法,欢送留言评论!

正文完
 0