网络知识点汇总

谈起计算机网络,不得不祭出这张图。

2020-09-20-OSI-TCPIP

# 1. 当浏览器输入一个url请求会经历什么?

主要流程大致如下:

  • DNS 域名解析
  • 建立 TCP 连接(三次握手)
  • 发起 HTTP 请求(Request)
  • 服务器处理请求,浏览器接受 HTTP 响应(Response)
  • 浏览器解析渲染页面
  • 连接结束(四次挥手) 下面解释下各部分。

贴一张画的很全面的图(来自https://juejin.im/post/6864175613209640973,侵删)。

2020-09-20-url

# 1.1 DNS 域名解析

浏览器 DNS 缓存 -> 本地 hosts 文件 -> 本地 DNS 解析器缓存 -> 本地 DNS 服务器(具有权威性)-> 非本地 DNS 服务器区域有缓存(不具有权威性)-> 本地 DNS 服务器迭代查询(根、二级、三级...),查询到之后,先缓存再返回给客户机。

# 1.2 三次握手

发送端 SYN = 1, seq = x -> 接收端 SYN = 1, ACK = 1, seq = y, ack= x + 1 -> 发送端 ACK = 1, seq = x + 1, ack = y + 1。

为什么TCP客户端最后还要发送一次确认呢?

主要是为了防止已经失效的连接请求报文突然又传到服务器,产生错误和资源浪费。

# 1.3 发起 HTTP 请求

完整的 HTTP 请求包括起始行、请求头部、请求主体三部分。 请求方法有:

  • GET:获取资源
  • POST:传输实体主体
  • PUT:传输文件
  • DELETE:删除文件
  • HEAD:获取报文首部
  • OPTIONS:询问支持的方法
  • TRACE:追踪路径

GET 和 POST 的区别:

  • GET 请求没有 body,只有 url,请求数据放在 url 的 querystring 中;POST 请求的数据在 body 中,通常来自于表单提交。
  • 所以,GET 请求对访问数据没有副作用,POST 有副作用,就好比数据库中的查询和更新。
  • 因此,GET 可以被缓存,而 POST 不能缓存,也不能被收藏为书签。

# 1.4 接收 HTTP 响应

服务器受到浏览器发送的 HTTP 请求后,会将 HTTP 报文封装成 HTTP 的 Request 对象,并通过不同的 Web 服务器进行处理,处理完的结果以 HTTP 的 Response 对象返回,主要包括状态码,响应头和响应报文三部分。

⚠️ 注意,TCP 规定

  • SYN 报文段不能携带数据,但要消耗一个序号
  • ACK 报文可以携带数据,但如果不携带数据则不消耗序号
  • FIN 报文段可以携带数据,但即使不携带数据也要消耗一个序号。

为什么建立连接时三次握手而关闭连接要四次握手?

建立连接的时候,服务器在 LISTEN 状态下,收到建立连接请求的 SYN 的报文后,把 ACK 和 SYN 放在同一个报文段里发送给客户端。 而关闭连接的时候,服务器收到对方的 FIN 报文段,只是表示对方不再发送数据了但还能接收数据,此时服务器也未必已经发送完所有的数据了,因此服务器可以立即关闭,也可以发送完剩下的数据后再发送 FIN 报文段表示同意关闭连接,所以服务器的 ACK 和 FIN 一般都会分开发送,导致多了一次挥手。

如果已经建立了连接,但客户端故障了怎么办?

服务器设置了一个保活计时器来避免资源浪费,一般是 2 个小时,如果连接建立后一直没有收到客户端的数据,那么在保活计时器超时之后,服务器就会发送一个探测报文,以后每隔 75 分钟发送一个,若一连 10 个探测报文都没有回应,则服务器认为客户端故障,主动关闭连接。

# 1.5 浏览器解析渲染页面

  • 构建文档对象模型(DOM)
  • 构建 CSS 对象模型(CSSOM)
  • 构建渲染树(Render Tree)
  • 布局
  • 绘制

# 1.6 关闭连接(四次挥手)

浏览器发完数据后,发送 FIN 请求断开连接 -> 服务器发送 ACK 表示同意 -> 服务器发送 FIN 请求断开连接 -> 浏览器发送 ACK 表示同意。

# 2. DNS 服务器

DNS 服务器分为三类:根 DNS 服务器,顶级域 DNS 服务器,权威 DNS 服务器。

DSN 查询有递归查询和迭代查询,其区别如下:

  • 递归查询:必须返回一个准确的查询结果,如果该 DNS 服务器没有查到,那么就会成为代理去询问其他服务器。
  • 迭代查询:DNS 服务器会像请求端返回其他能够解释查询的 DNS 服务器。

一般情况下,从请求主机到本地 DNS 服务器的查询是递归的,其余查询是迭代的。

# 3. TCP 与 UDP

# 3.1 优劣对比

TCP UDP
连接状态 面向连接 无连接
可靠性 可靠交付 尽最大努力交付
实时性 效率比 UDP 低 实时性好
收发方 点对点 一对一/多,多对一/多都可
系统资源需求 较高 较少
备注 TCP 通过流量控制、序号、确认和定时器,确保正确、按序将数据从发送进程交付给接收进程 适用于对高速传输和实时性要求较高的通信或广播通信,且对数据安全性无特殊要求

# 3.2 TCP 发送方

超时重传,快重传。

快重传:在某报文段的定时器过期之前重传丢失的报文段。

# 3.3 TCP 接收方

累计确认,差错恢复。

虽然 TCP 是累计确认(类似 Go-Back-N,GBN 协议),但是它会缓存失序报文段,且允许接收方有选择地确认失序报文段,这就使得发送方可以选择重传(类似 Select-Repeat,SR 协议)。 因此,TCP 的差错恢复机制为 GBN 协议和 SR 协议的混合体。

# 3.4 TCP 流量控制与拥塞控制

都是对发送方的遏制。

流量控制是流量控制也是一个速率匹配服务,是为了避免接收方缓存溢出的。它其实是一个速率匹配服务,让发送方发送但未被确认的数据量小于接收方的接收窗口大小(rwnd 是动态变化的),就可以保证接收方缓存不会溢出。

拥塞控制是一个全局性的过程,为了避免过多数据注入到网络中,保证路由器或链路不过载的。拥塞的标志可以说是重传计时器超时或接收到三个重复确认。相关算法有慢启动算法、拥塞避免算法(使网络比较不容易拥塞而不是完全避免)、快重传、快恢复。

# 4. HTTP 协议

HTTP 协议包括两种报文:请求(Request)报文和响应(Response)报文,这里有很详细的解释。

https://juejin.im/post/6864175613209640973#heading-26

Cookie 和 Session 是用户识别和状态管理的机制,都是会话技术。

Cookie Session
运行 在客户端(浏览器) 在服务器
限制 大小4K,且个数也有限制 与服务器内存相关
备注 有安全隐患,通过拦截或本地文件找到你的 Cookie 后可以进行攻击 Session 保存在服务器上一段时间后才会消失,如果 Session 过多会增加服务器的压力

# 5.1 同域验证

由于 HTTP 是无状态的,一次请求结束,连接断开,下次服务器再收到请求,它就不知道这是哪个用户发过来的了,因而需要状态管理,以便服务器知道 HTTP 请求的发起者,从而判断该用户是否有权限继续这个请求,这个过程就是会话管理。

如果前端,后台 API 部署在同域下,登录方式相对简单,有以下两种:

  • 基于 Session 登录:用 Cookie(在 HTTP header 中) 存储 Sessionid,在服务器 Session 中判断是否有登录凭证。
  • 基于 Token 登录:用 Token(放到 URL 参数或 HTTP header 中) 去服务器解密并检查其内部的登录凭证是否有效。

# 5.2 跨域验证

浏览器具有同源策略,凡是发送请求的 URL、域名、端口号有一个与当前页面不同则视为跨域。

而浏览器不能跨域读取 Cookie 信息,因此,当客户端跨域访问时,浏览器不能读取先前跨域的服务器返回的 Cookie 信息,而服务器检测不到客户端请求里的会话信息,就判断客户端没有登录

需要两步解决跨域问题

  • 解决同源问题:在服务器设置 Access-Control-Allow-HeaderAccess-Control-Allow-Origin 为星号,若要发送 Cookie,则 Origin 不能设置星号,需要设置为明确的、与客户端一致的域名。
  • 请求带上 Cookie 信息:CORS 默认不发送 Cookie 和 HTTP 认证信息,因此服务器需要指定 Access-Control-Allow-Credentials: true,另一方面需要在客户端的请求中添加 withCredentials 属性。

# 6. HTTP

影响 HTTP 网络请求的因素主要有两个:带宽和延迟。

HTTP1.0 与 HTTP1.1 的区别(对缓断续错享长)

HTTP1.0 HTTP1.1
缓存处理 强制缓存 对比缓存
带宽优化和网络连接的使用 需 Part 给 ALL 支持断点续传
错误通知管理 xx 新增 24 个错误状态响应码
Host 头处理 xx 虚拟主机共享 IP
长连接 每次请求都要三次握手 持久化连接和管线化处理

把添加了加密、认证机制、完整性保护的 HTTP 称为 HTTPS。

关于 HTTPS 的解释,个人认为这里讲的比较通俗。

# 7. WebSocket

HTML5 开始提供的一个全双工通信协议,建立连接时由客户端请求 HTTP 协议升级,握手成功后,使用 WebSocket 协议进行通信。

WebSocket 采用心跳来确保 TCP 通道保持连接没有断开(ping[0x9]、pong[0xA])。