Skip to content

网络通信数据传输机制 ​

掌握网络与服务器工作机制的重要性

掌握网络的基本原理、数据传输规则与服务器规则机制,才能有所针对性地去优化网页资源的请求、加载、处理与调度等。

网络七层模型 ​

七层模型,亦称OSI(Open System Interconnection),国际标准化组织(ISO)制定的一个用于计算机或通信系统间互联的标准体系,一般称为OSI参考模型或七层模型。

OSI 七层网络模型和 TCP/IP 四层网络模型

应用层 ​

主要功能:向用户提供服务,完成用户希望在网络上完成的各种工作。
相关协议:HTTP、FTP、TFTP、SMTP、SNMP、DNS、TELNET、HTTPS、POP3、DHCP等。

表示层 ​

主要功能:数据的表示、安全、压缩。
相关协议:JPEG、ASCll、DECOIC、加密格式等。

会话层 ​

会话层,对应主机进程,指本地主机与远程主机正在进行的会话。
主要功能:建立、管理、终止会话。

传输层 ​

主要功能:监控数据传输服务的质量,保证报文的正确传输。例如当发送大量数据时,很可能会出现丢包的情况,另一台电脑要告诉是否完整接收到全部的包。如果缺了,就告诉丢了哪些包,然后再发一次,直至全部接收为止。 工作职责:定义传输数据的协议端口号,以及流控和差错校验,数据包一旦离开网卡即进入网络传输层。 相关协议:TCP、UDP等。

网络层 ​

主要功能:进行逻辑地址寻址,实现不同网络之间的路径选择。
相关协议:ICMP、IGMP、IP(IPV4 IPV6)等。

数据链路层 ​

工作职责:接收来自物理层的位流形式的数据,并封装成帧,传送到上一层;同样,也将来自上层的数据帧,拆装为位流形式的数据转发到物理层。
主要功能:建立逻辑连接、进行硬件地址寻址、差错校验,将比特组合成字节进而组合成帧,用MAC地址访问介质,错误发现但不能纠正。

物理层 ​

工作职责:传输比特流(就是由1、0转化为电流强弱来进行传输,到达目的地后在转化为1、0,也就是我们常说的数模转换与模数转换)。
主要功能:建立、维护、断开物理连接,即硬件之间通信问题,例如光纤、电缆、中继器等,它们主要定义物理设备标准,例如网线的接口类型、光纤的接口类型、各种传输介质的传输速率等。

HTTP协议 ​

HTTP (The HyperText Transfer Protocol),即超文本传输协议,是用于在 Web 上传输超媒体文件的底层协议,最典型场景的是在浏览器和服务器之间传递数据,以供人们浏览。

注意事项

HTTP的URL是由“http://”起始与默认使用端口80。

基本特征

  • 文本化:所有的通信都以纯文本的形式进行。
  • 无状态:当前通信状态不会发现以前的通信状态。

HTTP/0.9 ​

HTTP 0.9是Tim Berners-Lee在1990年为了推动万维网的应用而设计的简单协议。

基本特征

HTTP 0.9 请求只有一行,包括 GET 方法和要请求的文档的路径。响应是一个超文本文档,没有首部,也没有其他元数据,只有 HTML。

  • 实现功能

    • 客户端 / 服务器、请求 / 响应协议;
    • ASCII 协议,运行于 TCP/IP 链接之上;
    • 设计用来传输超文本文档(HTML);
    • 服务器与客户端之间的连接在每次请求之后都会关闭。
  • HTTP 0.9 协议内容

    telnet perf.ysunlight.com 80
    
    Connected to 74.125.xxx.xxx
    
    GET /about/
    
    (超文本响应)
    (连接关闭)
  • 协议内容要点

    • 请求只有一行,包括 GET 方法和要请求的文档的路径。
    • 响应是一个超文本文档,没有首部,也没有其他元数据,只有 HTML。

HTTP/1.0 ​

1996 年,HTTP 工作组发布了 RFC 1945,解释说明了当时很多 HTTP 1.0 实现的“公共用法”。但是,HTTP 1.0 并不是一个正式的规范或互联网标准。

历史背景

随着人们对新兴 Web 的需求越来越多,以及它们在公共 Web 上的应用迅速爆发,HTTP 0.9 的很多根本性不足便暴露出来。人们需要一种协议,它不仅能访问超文本文档,还能提供有关请求和响应的各种元数据,而且要支持内容协商等。

  • 现功能

    • 媒体类型协商
    • 内容编码
    • 字符集支持
    • 多部分类型
    • 认证
    • 缓存
    • 代理行为
    • 日期格式
  • HTTP 1.0 协议内容

telnet perf.ysunlight.com 80

Connected to 74.125.xxx.xxx

GET /rfc/rfc1945.txt HTTP/1.0 1️⃣
User-Agent: CERN-LineMode/2.15 libwww/2.17b3
Accept: */*

HTTP/1.0 200 OK 2️⃣ 

Content-Type: text/plain
Content-Length: 137582
Expires: Thu, 01 Dec 1997 16:00:00 GMT
Last-Modified: Wed, 1 May 1996 12:45:26 GMT
Server: Apache 0.84

(超文本响应)
(连接关闭)
  • 协议内容要点
    1. 请求行中包含 HTTP 版本号,随后是请求首部
    2. 响应状态,后跟响应首部

HTTP/1.1 ​

是 1997年1月,定义正式 HTTP 1.1 标准的 RFC 2068 发布。1999年6月 RFC 2616 发布,又在标准中集合了很多改进和更新。

  • 新增功能

    • 持久连接
    • 分块编码传输
    • 字节范围请求
    • 增强的缓存机制
    • 传输编码及请求管道
    • 客户端 cookie
  • HTTP 1.1 协议内容

telnet perf.ysunlight.com 80

Connected to 74.125.xxx.xxx

GET /index.html HTTP/1.1 1️⃣
Host: website.org
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4)... (snip)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: __qca=P0-800083390... (snip)

HTTP/1.1 200 OK 2️⃣

Server: nginx/1.0.11
Connection: keep-alive
Content-Type: text/html; charset=utf-8
Via: HTTP/1.1 GWA
Date: Wed, 25 Jul 2012 20:23:35 GMT
Expires: Wed, 25 Jul 2012 20:23:35 GMT
Cache-Control: max-age=0, no-cache
Transfer-Encoding: chunked

100 3️⃣
<!doctype html>
(snip)
100
(snip)

0 4️⃣

GET /favicon.ico HTTP/1.1 5️⃣
Host: www.website.org
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4)... (snip)
Accept: */*
Referer: http://website.org/
Connection: close 6️⃣
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: __qca=P0-800083390... (snip)

HTTP/1.1 200 OK 7️⃣
Server: nginx/1.0.11

Content-Type: image/x-icon
Content-Length: 3638
Connection: close
Last-Modified: Thu, 19 Jul 2012 17:51:44 GMT
Cache-Control: max-age=315360000
Accept-Ranges: bytes
Via: HTTP/1.1 GWA
Date: Sat, 21 Jul 2012 21:35:22 GMT
Expires: Thu, 31 Dec 2037 23:55:55 GMT
Etag: W/PSA-GAu26oXbDi

(超文本响应)
(连接关闭)

请求头 ​

GET /static/widgets/abandon-redeem/abandon-redeem.min.js HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
Cache-Control: no-cache
Connection: keep-alive
Cookie: fpestid=oweWK_spULYSzMLJ82gC-PWz78vyNp9rwozuVcbFbcgaMEH2W0InoL7luL5ga2wgRe9xrw
Host: ig-imgz.feierfitness.com
Pragma: no-cache
Referer: https://ysungod.myshopify.com/
Sec-Fetch-Dest: script
Sec-Fetch-Mode: no-cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 Edg/125.0.0.0
sec-ch-ua: "Microsoft Edge";v="125", "Chromium";v="125", "Not.A/Brand";v="24"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "macOS"

响应头 ​

HTTP/1.1 200 OK
Last-Modified: Thu, 30 May 2024 00:58:54 GMT
Content-Encoding: gzip
Etag: "58508006be35906837b5d4b84e16cb26"
Content-Type: text/javascript
Date: Thu, 30 May 2024 01:00:42 GMT
Server: tencent-cos
x-cos-hash-crc64ecma: 6668125860949527541
x-cos-request-id: NjY1N2NmYmFfMzZmMDVlMGJfMjZmODhfMWM1Nzc0MA==
Content-Length: 7444
Accept-Ranges: bytes
X-NWS-LOG-UUID: 7181319309533639413
Connection: keep-alive
X-Cache-Lookup: Cache Hit
Access-Control-Allow-Origin: *

优化核心 ​

消除和减少不必要的网络延迟 把传输的字节数降到最少

高性能网站建设指南 ​

减少HTTP请求:任何请求都不如没有请求更快,因此要去掉页面上没有必要的资源。 使用内容发布网络 添加Expires头 压缩组件 将样式表放在顶部 将脚本放在底部 避免CSS表达式 使用外部javascript与css 减少DNS查找:每次域名解析都需要一次网络往返,增加请求的延迟,在查询期间会阻塞请求。 精简javascript 避免重定向 移除重复脚本 配置Etag 使ajax可缓存

使用CDN:从地理上把数据放到接近客户端的地方,可以显著减少每次 TCP 连接的网络延迟,增加吞吐量。 Gzip资源

  • 协议内容要点
    1. 请求 HTML 文件,及其编码、字符集和元数据
    2. 对原始 HTML 请求的分块响应
    3. 以 ASCII 十六进制数字表示的分块数据的字节数(256 字节)
    4. 分块数据流响应结束
    5. 在同一个 TCP 连接上请求图标文件
    6. 通知服务器不再使用连接了
    7. 图标响应,随后关闭连接

HTTP 管道 ​

HTTP 管道,即充分利用服务器空闲的时间,以并行或在多线程上或者使用多个工作进程,同时处理两个或多个请求,最终将多个请求结果一次性返回,从而减少了每次请求单独返回的性能损耗问题。

HTTP/1.X缺陷 ​

连接无法复用,每次请求需要重新建立连接。 请求并发数量的限制,限制约束了前端资源的加载。 协议传输冗余数据问题,造成带宽上的浪费。 协议内容安全问题,明文容易造成数据泄漏。

HTTP1.0与HTTP1.1最大并发连接数限制 ​

HTTP/2.X ​

HTTP/2 是 HTTP 网络协议的一个重要版本。 HTTP/2的主要目标是通过启用完整的请求和响应多路复用来减少 延迟,通过有效压缩HTTP标头字段来最小化协议开销,并增加对请求优先级和服务器推送的支持。通过支持请求与响应的多路复用来减少延迟,通过压缩 HTTP首部字段将协议开销降至最低,同时增加对请求优先级和服务器端推送的支持。

主要目标

改进传输性能,实现低延迟和高吞吐量。

  • 新增功能
    • 二进制分帧数据层:如何封装 HTTP 消息并在客户端与服务器之间传输。
  • HTTP 2.x 协议内容

帧、消息和数据流 ​

帧(frame):可以理解为一个连续的消息流中的一个片段,是最小单位。HTTP 2.0 通信的最小单位,每个帧包含帧首部,至少也会标识出当前帧所属的流。 消息(message):对应于HTTP1中的请求或者响应,包含一条或者多条message。与逻辑消息对应的完整的一系列数据帧。 数据流(stream):包含1条或者多条message。已建立的连接上的双向字节流

实现原理 | 应用层和传输层之间增加了一个二进制分帧层 ​

修改了格式化数据(分帧)的方式,以及客户端与服务器间传输这些数据的方式 HTTP 2.0 的所有帧都采用二进制编码,所有首部数据都会被压缩 所有通信都在一个 TCP 连接上完成 HTTP 2.0 把 HTTP 协议通信的基本单位缩小为一个一个的帧,这些帧对应着逻辑流中的消息 很多流可以并行地在同一个 TCP 连接上交换消息

二进制分帧数据层 ​

HTTP 1.x 以换行符作为纯文本的分隔符,而 HTTP2.0 将所有传输的信息分割为更小的消息和帧,并对它们采用二进制格式的编码。二进制分帧层通过将所有传输的信息分割为更小的消息和帧,并采用二进制格式进行编码,其中,HTTP1.1中的首部信息header封装到Headers帧中,而request body则封装到Data帧中。 HTTP2的通信都在一个TCP连接上完成,这个连接可以承载任意数量的双向数据流,相应的每个数据流以消息的形式发送,而消息由一个或多个帧组成,这些帧可以乱序发送,然后根据每个帧的首部流标识符重新组装。

其他 ​

每一帧的数据大小限制:

流、消息和帧 ​

所有 HTTP 2.0 通信都在一个连接上完成,这个连接可以承载任意数量的双向数据流。相应地,每个数据流以消息的形式发送,而消息由一或多个帧组成,这些帧可以乱序发送,然后再根据每个帧首部的流标识符重新组装。所有帧都采用二进制编码,所有首部数据都会被压缩。

  • 流:已建立的连接上的双向字节流,每个流都有一个唯一的整数标识符。
  • 帧:HTTP 2.0 通信的最小单位,每个帧包含帧首部,至少也会标识出当前帧所属的流,例如HTTP首部、负荷等。
  • 消息:与逻辑消息对应的完整的一系列数据帧,比如请求、响应等,由一或多个帧组成。

HTTP 2.0 流、消息和帧

二进制分帧层 ​

二进制分帧层,指位于套接字接口与应用可见的高层 HTTP API 之间的一个新机制。其中,HTTP 的语义,包括各种动词、方法、首部,都不受影响,但是改变了传输期间对它们的编码方式。

编码方式

HTTP 1.x 以换行符作为纯文本的分隔符,而 HTTP2.0 将所有传输的信息分割为更小的消息和帧,并对它们采用二进制格式的编码。

HTTP 2.0 二进制分帧层

多路复用 ​

基于二进制帧分层,将多个请求数据在同一个TCP连接中进行传输,有效解决了HTTP/1.X对请求并发数量的限制问题。

流量控制 ​

服务器推送 ​

HTTP/3.X ​

HTTP/3.X是基于QUIC而实现HTTP传输的新技术。

QUIC ​

QUIC 是一种基于 UDP 的流多路复用加密传输协议。

QUIC 版本历史 ​

  • 2012 年,Google 开始开发 QUIC
  • 2013 年,Chrome 开始对 QUIC 的原始版本(这些版本现在称为 Google QUIC)进行小规模实验
  • 2014 年,Chrome 开始大规模部署 Google QUIC
  • 2015 年,Google 将 QUIC 引入 IETF
  • 2017 年,IETF 开始创建与 Google QUIC 不同的 QUIC 版本(这些新版本当时称为 IETF QUIC)
  • 2020 年,Chrome 开始对 IETF QUIC 进行大规模实验
  • 2021 年,IETF 正式将 QUIC 发布为 RFC 9000。Chrome 在 Chrome 9000 中添加了对 RFC 90 的支持,并在 Chrome 93 中为所有用户默认启用了 RFC

HTTPS ​

HTTPS(安全的HTTP)是 HTTP 协议的加密版本,通常使用 SSL 或者 TLS 来加密客户端和服务器之间所有的通信,提供对网站服务器的身份认证,保护交换资料的隐私与完整性。

注意事项

HTTPS的URL则是由“https://”起始与默认使用端口443。

注意事项

HTTPS增加了TLS握手的往返网络开销。

SSL ​

安全套接字层(Secure Sockets Layer),

TLS1.0 ​

传输层安全(Transport Layer Security),

TLS 4次握手 ​

  • Client Hello:

由于客户端(如浏览器)对一些加解密算法的支持程度不一样,但是在TLS协议传输过程中必须使用同一套加解密算法才能保证数据能够正常的加解密。在TLS握手阶段,客户端首先要告知服务端,自己支持哪些加密算法,所以客户端需要将本地支持的加密套件(Cipher Suite)的列表传送给服务端。除此之外,客户端还要产生一个随机数,这个随机数一方面需要在客户端保存,另一方面需要传送给服务端,客户端的随机数需要跟服务端产生的随机数结合起来产生后面要讲到的Master Secret。

  • Server Hello:

上图中,从Server Hello到Server Done,有些服务端的实现是每条单独发送,有服务端实现是合并到一起发送。Sever Hello和Server Done都是只有头没有内容的数据。服务端在接收到客户端的Client Hello之后,服务端需要将自己的证书发送给客户端。这个证书是对于服务端的一种认证。例如,客户端收到了一个来自于称自己是www.alipay.com的数据,但是如何证明对方是合法的alipay支付宝呢?这就是证书的作用,支付宝的证书可以证明它是alipay,而不是财付通。证书是需要申请,并由专门的数字证书认证机构(CA)通过非常严格的审核之后颁发的电子证书。颁发证书的同时会产生一个私钥和公钥。私钥由服务端自己保存,不可泄漏。公钥则是附带在证书的信息中,可以公开的。证书本身也附带一个证书电子签名,这个签名用来验证证书的完整性和真实性,可以防止证书被串改。另外,证书还有个有效期。

在服务端向客户端发送的证书中没有提供足够的信息的时候,还可以向客户端发送一个Server Key Exchange。

此外,对于非常重要的保密数据,服务端还需要对客户端进行验证,以保证数据传送给了安全的合法的客户端。服务端可以向客户端发出Cerficate Request消息,要求客户端发送证书对客户端的合法性进行验证。

跟客户端一样,服务端也需要产生一个随机数发送给客户端。客户端和服务端都需要使用这两个随机数来产生Master Secret。

最后服务端会发送一个Server Hello Done消息给客户端,表示Server Hello消息结束了。

  • Client Key Exchange: 如果服务端需要对客户端进行验证,在客户端收到服务端的Server Hello消息之后,首先需要向服务端发送客户端的证书,让服务端来验证客户端的合法性。

在此之前的所有TLS握手信息都是明文传送的。在收到服务端的证书等信息之后,客户端会使用一些加密算法(例如:RSA, Diffie-Hellman)产生一个48个字节的Key,这个Key叫PreMaster Secret,很多材料上也被称作PreMaster Key, 最终通过Master secret生成session secret, session secret就是用来对应用数据进行加解密的。PreMaster secret属于一个保密的Key,只要截获PreMaster secret,就可以通过之前明文传送的随机数,最终计算出session secret,所以PreMaster secret使用RSA非对称加密的方式,使用服务端传过来的公钥进行加密,然后传给服务端。

接着,客户端需要对服务端的证书进行检查,检查证书的完整性以及证书跟服务端域名是否吻合。

ChangeCipherSpec是一个独立的协议,体现在数据包中就是一个字节的数据,用于告知服务端,客户端已经切换到之前协商好的加密套件的状态,准备使用之前协商好的加密套件加密数据并传输了。

在ChangecipherSpec传输完毕之后,客户端会使用之前协商好的加密套件和session secret加密一段Finish的数据传送给服务端,此数据是为了在正式传输应用数据之前对刚刚握手建立起来的加解密通道进行验证。

  • Server Finish: 服务端在接收到客户端传过来的PreMaster加密数据之后,使用私钥对这段加密数据进行解密,并对数据进行验证,也会使用跟客户端同样的方式生成session secret,一切准备好之后,会给客户端发送一个ChangeCipherSpec,告知客户端已经切换到协商过的加密套件状态,准备使用加密套件和session secret加密数据了。之后,服务端也会使用session secret加密后一段Finish消息发送给客户端,以验证之前通过握手建立起来的加解密通道是否成功。

根据之前的握手信息,如果客户端和服务端都能对Finish信息进行正常加解密且消息正确的被验证,则说明握手通道已经建立成功,接下来,双方可以使用上面产生的session secret对数据进行加密传输了。

  • 0 ms:TLS 在可靠的传输层(TCP)之上运行,这意味着首先必须完成 TCP 的“三次握手”,即一次完整的往返。
  • 56 ms:TCP 连接建立之后,客户端再以纯文本形式发送一些规格说明,比如它所运行的 TLS 协议的版本、它所支持的加密套件列表,以及它支持或希望使用的另外一 些 TLS 选项。
  • 84 ms:然后,服务器取得 TLS 协议版本以备将来通信使用,从客户端提供的加密套件列表中选择一个,再附上自己的证书,将响应发送回客户端。作为可选项,服务器也可以发送一个请求,要求客户端提供证书以及其他 TLS 扩展参数。
  • 112 ms:假设两端经过协商确定了共同的版本和加密套件,客户端也高高兴兴地把自己的证书提供给了服务器。然后,客户端会生成一个新的对称密钥,用服务器的公钥来加密,加密后发送给服务器,告诉服务器可以开始加密通信了。到目前为止,除了用服务器公钥加密的新对称密钥之外,所有数据都以明文形式发送。
  • 140 ms:最后,服务器解密出客户端发来的对称密钥,通过验证消息的 MAC 检测消息完整性,再返回给客户端一个加密的“Finished”消息。
  • 168 ms:客户端用它之前生成的对称密钥解密这条消息,验证 MAC,如果一切顺利,则建立信道并开始发送应用数据。

HTTP 缓存 ​

HTTP 缓存:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Caching Cache-Control:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Cache-Control HTTP 缓存:https://www.chromium.org/developers/design-documents/network-stack/http-cache/

浏览器缓存Size显示类型 ​

200(from disk cache):资源缓存在内存中,浏览器关闭后生命周期结束
200(from memory cache):资源缓存在硬盘中
200(from ServiceWorker):PWA部署缓存 304(Not Modified):向服务器发起网络请求,服务器来判断浏览器本地缓存有效,则服务器不返回资源,浏览器继续从缓存中加载资源

三级缓存原理 ​

从内存中查询,若存在,从内存中加载
内存中未找到,从硬盘中查询,若存在,从硬盘中加载
硬盘中未找到,从服务器发起网络请求资源

简介与核心思想 ​

缓存命中率:从缓存中得到数据的请求数与所有请求数的比率。理想状态是越高越好。
过期内容:超过设置的有效时间,被标记为“陈旧”的内容。通常过期内容不能用于回复客户端的请求,必须重新向源服务器请求新的内容或者验证缓存的内容是否仍然准备。
验证:验证缓存中的过期内容是否仍然有效,验证通过的话刷新过期时间。
失效:失效就是把内容从缓存中移除。当内容发生改变时就必须移除失效的内容。

浏览器的缓存时间 ​

大概10分钟左右,即(访问时间 - 最后修改时间) ÷ 10

缓存分类 ​

强缓存
协商缓存

强缓存 ​

利用http的返回头中的Expires或者Cache-Control两个字段来控制的,用来表示资源的缓存时间
命中强缓存时,浏览器并不会将请求发送给服务器。在Chrome的开发者工具中看到http的返回码是200,但是在Size列会显示为(from cache)

协商缓存 ​

若未命中强缓存,则浏览器会将请求发送至服务器, 服务器根据http头信息中的Last-Modify/If-Modify-Since或Etag/If-None-Match来判断是否命中协商缓存,如果命中,则http返回码为304,浏览器从缓存中加载资源

浏览器加载一个页面的简单流程-缓存机制 ​

浏览器先根据这个资源的http头信息来判断是否命中强缓存。如果命中则直接加在缓存中的资源,并不会将请求发送到服务器。
如果未命中强缓存,则浏览器会将资源加载请求发送到服务器。服务器来判断浏览器本地缓存是否失效。若可以使用,则服务器并不会返回资源信息,浏览器继续从缓存加载资源。
如果未命中协商缓存,则服务器会将完整的资源返回给浏览器,浏览器加载新资源,并更新缓存。

Cache-Control、Expires、Etag 和 Last-Modified 来设置 HTTP 缓存

<!--禁止浏览器从本地计算机的缓存中访问页面内容-->
<meta http-equiv="Pragma" content="no-store">
<meta http-equiv="Cache" content="no-cache">
<!--网页到期时间-->
<meta http-equiv="expires" content="Wed, 20 Jun 2020 22:33:00 GMT" />
<meta http-equiv="Cache-control" content="no-cache">
<!--
  no-cache,协商缓存,浏览器和缓存服务器都不应该缓存页面信息;
  public,浏览器和缓存服务器都可以缓存页面信息;
  no-store,不缓存,请求和响应的信息都不应该被存储在对方的磁盘系统中;
  must-revalidate,过期强制请求服务器,对于客户机的每次请求,代理服务器必须想服务器验证缓存是否过时;
-->

expires 值为一个绝对时间的 GMT 格式的时间字符串,如果发送请求的时间在 expires 之前,那么本地缓存有效,否则就会发送请求到服务器来获取资源。 缺点:无法保证客户端按照标准时间设定

Cache-Control(常用值): max-age:允许的最大缓存秒数 no-store:不允许使用缓存,每次都要向服务器获取 no-cache:不允许使用本地缓存,每次都要向服务器进行协商缓存 public:允许被所有中间代理和终端浏览器缓存 private:只允许被终端浏览器缓存 Cache-Control 比 expires 优先级高

REST服务 ​

REST(Representational State Transfer),即具象状态传输,是一组实现效率、可读性、还有可拓展分散式系统的软件架构设计规范。

General ​

文本内容 ​

Request URL: http://127.0.0.1:8099/req
Request Method: POST
Status Code: 200 OK
Remote Address: 127.0.0.1:8099
Referrer Policy: no-referrer-when-downgrade

请求网址: https://www.baidu.com/
请求方法: GET
状态代码: 200 OK
远程地址: 183.2.172.185:443
引荐来源网址政策: strict-origin-when-cross-origin

Request Headers ​

在nginx的配置文件中进行配置,限制请求报文体的大小,nginx默认大小是1M。

文本内容 ​

Content-type: application/x-www-form-urlencoded
Origin: http://127.0.0.1:7901
Referer: http://127.0.0.1:7901/ajax/test/index.html
Sec-Fetch-Mode: cors
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36


GET / HTTP/1.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: zh-CN,zh;q=0.9
Cache-Control: no-cache
Connection: keep-alive
Cookie: PSTM=1700009769; BDRCVFR[S4-dAuiWMmn]=I67x6TjHwwYf0
Host: www.baidu.com
Pragma: no-cache
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36
sec-ch-ua: "Not A(Brand";v="99", "Google Chrome";v="121", "Chromium";v="121"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "macOS"

Response Headers ​

文本内容 ​

Access-Control-Allow-Origin: *
Connection: keep-alive
Content-Type: text/json
Date: Thu, 30 Jan 2020 12:47:52 GMT
Transfer-Encoding: chunked


HTTP/1.1 200 OK
Connection: keep-alive
Content-Encoding: gzip
Content-Security-Policy: frame-ancestors 'self' https://chat.baidu.com http://mirror-chat.baidu.com https://fj-chat.baidu.com https://hba-chat.baidu.com https://hbe-chat.baidu.com https://njjs-chat.baidu.com https://nj-chat.baidu.com https://hna-chat.baidu.com https://hnb-chat.baidu.com http://debug.baidu-int.com;
Content-Type: text/html; charset=utf-8
Date: Wed, 15 Nov 2023 01:07:54 GMT
Server: BWS/1.1
Set-Cookie: H_PS_PSSID=39636_39670_39672_39663_39687_39690_39676_39679_39712_39731; path=/; expires=Thu, 14-Nov-24 01:07:54 GMT; domain=.baidu.com
Traceid: 1700010474235279668211066115467302408234
X-Ua-Compatible: IE=Edge,chrome=1
Transfer-Encoding: chunked

特殊字段 ​

Accept-Ranges    # 服务器告诉让客户端知道服务器接受以字节为单位的部分内容请求

TLS协议 ​

TLS(Transport Layer Security),即传输层安全性协议,前身是安全套接层(Secure Sockets Layer,缩写作SSL),是一个被应用程序用来在网络中安全通信的 protocol (通讯协议),防止电子邮件、网页、消息以及其他协议被篡改或是窃听。

重要通知

TLS协议采用主从式架构模型,用于在两个应用程序间透过网络创建起安全的连线,防止在交换资料时受到窃听及篡改,SSL 3.0 的升级版。

注意事项

为了建立加密的安全数据通道,连接双方必须就加密数据的密钥套件和密钥协商一致 。TLS 协议规定了一套严密的握手程序用于交换这些信息,客户端与服务器在通过 TLS 交换数据之前,必须协商建立加密信道。协商内容包括TLS 版本、加密套件,必要时还会验证证书。然而,协商过程的每一步都需要一个分组在客户端和服务器之间往返一次,因而所有 TLS 连接启动时都要经历一定的延迟。

传输层安全 (TLS)

三项基本服务 ​

  • 加密:一种混淆从一个主机发送到另一个主机的内容的机制。
  • 验证:一种验证所提供身份证明材料有效性的机制。
  • 数据完整性:一种检测消息篡改和伪造的机制。

建立TLS连接的四次握手 ​

TLS 握手协议

TLS 记录协议 ​

是一种分层协议,这种协议被用来封装几种高层协议(如HTTP,SMTP等)。使用有TLS握手协议产生的安全参数,它首先将上层被传输的数据分片成便于管理的块,然后对数据有选择性地压缩,计算出消息认证码MAC(如MD5或SHA),加密(如NULL,DES,3DES等),最后将结果送出。接收到的数据经过解密,校验,解压缩,重组后被传输到上层客户端。

重要通知

RFC2246中定义了TLS记录协议。

IP协议 ​

IP(Internet Protocol),即因特网协议,负责联网主机之间的路由选择和寻址,按照地址从源主机向目标主机发送数据报,消息会被封装在一个 IP 分组内,其中载明了源地址和目标地址,以及其他一些路由参数。

数据报 ​

IP 层不保证消息可靠的交付,也不发送失败通知,实际上是把底层网络的不可靠性直接暴露给了上一层。如果某个路由节点因为网络拥塞、负载过高或其他原因而删除了 IP 分组,那么在必要的情况下,IP 的上一层协议要负责检测、恢复和重发数据。

IPv4 ​

IPv4(Internet Protocol Version 4),即互联网协议第4版,IPv4 中的 4 表示 TCP/IP 协议的第 4个版本,发布于 1981 年 9 月。

注意事项

2019年11月26日,全球所有43亿个IPv4地址已分配完毕,这意味着没有更多的IPv4地址可以分配给ISP和其他大型网络基础设施提供商。

IPv6 ​

IPv6(Internet Protocol Version 6),即互联网协议第6版,是互联网工程任务组(IETF)设计的用于替代IPv4的下一代IP协议,其地址数量号称可以为全世界的每一粒沙子编上一个地址。

TCP协议 ​

TCP(Transmission Control Protocol),即传输控制协议,负责在不可靠的传输信道之上提供可靠的抽象层,向应用层隐藏了大多数网络通信的复杂细节,比如丢包重发、按序发送、拥塞控制及避免、数据完整等。 TCP 在1970年代被两位 DARPA 的科学家 Vint Cerf 和 Bob Kahn 所设计出来,他们当时被称为互联网之父。

重要通知

  • TCP协议的特征
    • 保证数据的交付
    • 维持数据包的发送顺序
    • 保证消息不重复
  • 适用范围
    • 需要差错和纠错的应用程序

注意事项

TCP 专门为精确传送做了优化,但并未过多顾及时间。这一点也给优化浏览器 Web 性能带来了挑战。

建立TCP连接的三次握手 ​

SYN(Synchronize Sequence Numbers):即同步序列编号,是TCP/IP建立连接时使用的握手信号。 ACK(Acknowledge character):即确认字符,是在数据通信中接收站发给发送站的一种传输类控制字符。 NAK(Negative Acknowledge):即否认字符,为接收站对所收到的报文进行检查,若发现错误,便向发送站发送否认回答NAK,表示报文有错,并要求重发。

  • 第一次握手:同步 SYN
    • 行为:客户端选择一个随机序列号x并发送一个 SYN 数据包,其中可能还包括额外的 TCP 标志和选项。
    • 消息:客户端发送网络包,服务端收到了。
  • 第二次握手:同步确认 SYN ACK
    • 行为:服务器递增x1,选择自己的随机序列号y,附加自己的一组标志和选项,然后发送响应。
    • 消息:服务端发包,客户端收到了 [此时服务器并不能确认客户端的接收能力是否正常]。
  • 第三次握手:确认 ACK
    • 行为:客户端将两者都加x一并y通过在握手中分派最后一个 ACK​​ 数据包来完成握手。
    • 消息:客户端发包,服务端收到了。

以HTML文档请求为例

重要通知

在三次握手协议中,服务器维护一个半连接队列,该队列为每个客户端的SYN包(syn=j)开设一个条目,该条目表明服务器已收到SYN包,并向客户发出确认,正在等待客户的确认包。

三次握手过程数据携带 ​

第一次不可以,因为存在安全问题,第一次如果可以携带数据,而服务器对客户端身份没有确认,倘若客户端属于恶意攻击者,那服务器在接收数据时,就会消耗大量资源。 例如:客户端疯狂着重复发 SYN 报文,服务器花费很多时间、内存空间来接收这些报文。

中断TCP连接的四次挥手 ​


  • 第一次挥手
    • 客户端发送一个 FIN 报文,报文中会指定一个序列号。此时客户端处于 FIN_WAIT1 状态。
    • 即发出连接释放报文段(FIN=1,序号seq=u),并停止再发送数据,主动关闭TCP连接,进入FIN_WAIT1(终止等待1)状态,等待服务端的确认。
  • 第二次挥手
    • 服务端收到 FIN 之后,会发送 ACK 报文,且把客户端的序列号值 +1 作为 ACK 报文的序列号值,表明已经收到客户端的报文了,此时服务端处于 CLOSE_WAIT 状态。
    • 即服务端收到连接释放报文段后即发出确认报文段(ACK=1,确认号ack=u+1,序号seq=v),服务端进入CLOSE_WAIT(关闭等待)状态,此时的TCP处于半关闭状态,客户端到服务端的连接释放。
    • 客户端收到服务端的确认后,进入FIN_WAIT2(终止等待2)状态,等待服务端发出的连接释放报文段。
  • 第三次挥手
    • 如果服务端也想断开连接了,和客户端的第一次挥手一样,发给 FIN 报文,且指定一个序列号。此时服务端处于 LAST_ACK 的状态。
    • 即服务端没有要向客户端发出的数据,服务端发出连接释放报文段(FIN=1,ACK=1,序号seq=w,确认号ack=u+1),服务端进入LAST_ACK(最后确认)状态,等待客户端的确认。
  • 第四次挥手
    • 客户端收到 FIN 之后,一样发送一个 ACK 报文作为应答,且把服务端的序列号值 +1 作为自己 ACK 报文的序列号值,此时客户端处于 TIME_WAIT 状态。
    • 需要过一阵子以确保服务端收到自己的 ACK 报文之后才会进入 CLOSED 状态,服务端收到 ACK 报文之后,就处于关闭连接了,处于 CLOSED 状态。
    • 即客户端收到服务端的连接释放报文段后,对此发出确认报文段(ACK=1,seq=u+1,ack=w+1),客户端进入TIME_WAIT(时间等待)状态。此时TCP未释放掉,需要经过时间等待计时器设置的时间2MSL后,客户端才进入CLOSED状态。

SYN攻击

通过发送大量的半连接请求,耗费CPU和内存资源。

SYN 攻击 ​

  • 在三次握手协议中,服务器维护一个半连接队列,该队列为每个客户端的SYN包(syn=j)开设一个条目,该条目表明服务器已收到SYN包,并向客户发出确认,正在等待客户的确认包。
  • 大量发送伪造源IP的SYN包也就是伪造第一次握手数据包,服务器每接收到一个SYN包就会为这个连接信息分配核心内存并放入半连接队列。
  • 如果短时间内接收到的SYN太多,半连接队列就会溢出,操作系统会把这个连接信息丢弃造成不能连接。
  • 当攻击的SYN包超过半连接队列的最大值时,正常的客户发送SYN数据包请求连接就会被服务器丢弃,每种操作系统半连接队列大小不一样所以抵御SYN攻击的能力也不一样。

TCP 快速打开 ​

TFO(TCP Fast Open),即TCP快速打开,是一种机制,旨在通过允许在 SYN 数据包内传输数据来消除对新 TCP 连接施加的延迟损失。

重要通知

Linux 3.7 及之后的内核已经在客户端和服务器中支持 TFO,因此成为了客户端和服务器操作系统选型的有力候选方案。

注意事项

TFO 并不能解决所有问题。它虽然有助于减少三次握手的往返时间,但却只能在某些情况下有效。比如,随同SYN 分组一起发送的数据净荷有最大尺寸限制、只能发送某些类型的 HTTP 请求,以及由于依赖加密 cookie,只能应用于重复的连接。

半连接队列 ​

服务器第一次收到客户端的 SYN 之后,就会处于 SYN_RCVD 状态,此时双方还没有完全建立其连接,服务器会把此种状态下请求连接放在一个队列里,我们把这种队列称之为半连接队列。

全连接队列 ​

就是已经完成三次握手,建立起连接的就会放在全连接队列中。如果队列满了就有可能会出现丢包现象

重要通知

为了避免拥塞崩溃故障。以便控制双向发送数据的速度,TCP加入很多机制,例如流量控制、拥塞控制和拥塞预防机制。

拥塞窗口cwnd ​

cwnd(congestion window),即拥塞窗口,拥塞窗口的大小取决于网络速度的拥塞程度和处理数据量,并且动态地在变化加入新的执行方式。

流量控制 ​

流量控制,是一种预防发送端过多向接收端发送数据的机制。

拥塞控制 ​

拥塞本身是发生在网络层的一种状态,当消息流量太忙,它减慢了网络响应时间。 服务器以TCP包发送数据,用户的客户端然后通过返回acknoledgements或ack来确认传输。 根据硬件和网络条件,连接的容量是有限的。 如果服务器发送太多的数据包太快,它们将被丢弃。 意味着,不会有任何确认。 服务器将其注册为丢失ACKs。 拥塞控制算法使用发送的数据包和ack流来确定发送速率。

拥塞预防机制 ​

拥塞预防算法把丢包作为网络拥塞的标志,即路径中某个连接或路由器已经拥堵了,以至于必须采取删包措施。因此,必须调整窗口大小,以避免造成更多的包丢失,从而保证网络畅通。

解决网络拥塞崩溃的几种算法 ​

  • 慢启动算法
    • 解决服务器和客户端之间关于确定拥塞窗口大小的最优值
  • 拥塞避免算法
  • 快重传算法
  • 快恢复算法

TCP 慢启动 ​

TCP 慢启动有助于提高网络能力的传输速度。它这样做时,最初并不知道这些功能是什么,也不会造成拥塞。TCP 慢启动是一种用于检测数据包传输可用带宽的算法,并平衡网络连接的速度。它可以防止出现最初未知功能的网络拥塞,并缓慢增加扩散的信息量,直到找到网络的最大容量。

  • 为了实现 TCP 慢启动,拥塞窗口 (cwnd) 设置了源在接收确认 (ACK) 之前可以通过网络传输的数据量的上限。慢启动阈值 (ssthresh) 决定了慢启动的(停用)激活。建立新连接时,cwnd 初始化为一个 TCP 数据或确认数据包,并等待确认或 ACK。收到该 ACK 后,拥塞窗口将递增,直到 cwnd 小于 ssthresh。当遇到拥塞时,慢启动也会终止。

14KB 规则 ​

第一个响应数据包是 14KB 大小的。这是慢启动的一部分,慢启动是一种均衡网络连接速度的算法。慢启动逐渐增加发送数据的数量直到达到网络的最大带宽。
在 TCP 慢启动 中,在收到初始包之后,服务器会将下一个数据包的大小加倍到大约 28KB。后续的数据包依次是前一个包大小的二倍直到达到预定的阈值,或者遇到拥塞。

队首阻塞HOL ​

HOL(Head of Line),即队首阻塞,每个 TCP 分组都会带着一个唯一的序列号被发出,而所有分组必须按顺序传送到接收端。如果中途有一个分组没能到达接收端,那么后续分组必须保存在接收端的 TCP 缓冲区,等待丢失的分组重发并到达接收端。这一切都发生在 TCP 层,应用程序对 TCP 重发和缓冲区中排队的分组一无所知,必须等待分组全部到达才能访问数据。在此之前,应用程序只能在通过套接字读数据时感觉到延迟交付。这种效应称为队首阻塞。

注意事项

按序交付和可靠交付有时候并不必要,反而会导致额外的延迟,对性能造成负面影响。

TCP 队首阻塞

重要通知

无需按序交付数据或能够处理分组丢失的应用程序,以及对延迟或抖动要求很高的应用程序,最好选择 UDP 等协议。

相关问题 ​

  • 重传次数有限制吗?具体限制次数是多少?
  • 握手等待时间有限制吗?具体限制时间是多少?
  • ISN(Initial Sequence Number)是固定的吗?
  • 三次握手过程中可以携带数据吗?
  • 如果第三次握手丢失了,客户端服务端会如何处理?
  • 四次挥手释放连接时,等待2MSL的意义?

UDP协议 ​

UDP(User Datagram Protocol),即用户数据报协议,是一个与 IP协议 一起使用的长期协议,用于在传输速度和效率比安全性和可靠性更重要的场合下发送数据,所有错误检测和错误纠正工作都可以委托给上层的应用程序。

  • UDP协议的特征
    • 不保证消息交付:不确认,不重传,无超时。
    • 不保证交付顺序:不设置包序号,不重排,不会发生队首阻塞。
    • 不保证消息不重复
    • 不跟踪连接状态:不必建立连接或重启状态机。
    • 不需要拥塞控制:不内置客户端或网络反馈机制。
  • 适用范围
    • 不需要差错和纠错的应用程序

实现原理 ​

简单地对IP进行的封装, UDP 协议会用自己的分组结构封装用户消息,它只增加了 4 个字段:源端口、目标端口、分组长度和校验和。这样,当 IP 把分组送达目标主机时,该主机能够拆开 UDP 分组,根据目标端口找到目标应用程序,然后再把消息发送过去。仅此而已。 说到底,UDP 仅仅是在 IP 层之上通过嵌入应用程序的源端口和目标端口,提供了一个“应用程序多路复用”机制。明白了这一点,就可以总结一下 UDP 的无服务是怎么回事了。 相对来说,UDP 数据报有明确的限制:数据报必须封装在 IP 分组中,应用程序必须读取完整的消息。换句话说,数据报不能分片。

数据报datagram ​

一个完整、独立的数据实体,携带着从源节点到目的地节点的足够信息,对这些节点间之前的数据交换和传输网络没有任何依赖。

分组package ​

分组可以用来指代任何格式化的数据块,而数据报则通常只用来描述那些通过不可靠的服务传输的分组,既不保证送达,也不发送失败通知。正

DNS域名系统 ​

域名,即将域名和IP地址相互映射的一个分布式数据库,使人更方便地访问互联网,而不用去记住能够被机器直接读取的IP地址数串。

同源策略 ​

同源:[协议]://[域名]:[端口]

DNS查询机制 ​

  • 浏览器:是否存在缓存
  • 操作系统:hosts文件是否存在映射IP
  • 路由器:
  • IPS服务器:
  • 根域名服务器:
  • 顶级域名服务器:
  • 主域名服务器:

递归查询 ​

递归查询,即本地域名服务器查询不到,则向其他域名服务器继续查询,直到查询为止,否则以报错返回给主机

迭代查询 ​

迭代查询, 即如果根域名服务器查询不到,则向本地域名服务器指定下一个所需查询的域名服务器,或以报错返回给本地域名服务器

LDNS,本地区域名服务器 ​

CDN内容分发网络 ​

CDN(Content Delivery Network),即内容分发网络,是构建在现有网络基础之上的智能虚拟网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。

基本原理 ​

广泛采用各种缓存服务器,将这些缓存服务器分布到用户访问相对集中的地区或网络中,在用户访问网站时,利用全局负载技术将用户的访问指向距离最近的工作正常的缓存服务器上,由缓存服务器直接响应用户请求。

备注 ​

除了TCP、UDP、HTTP等,其他协议还有流控制传输协议(SCTP)、RTSP、RTMP、HTTP-FLV、HLS等多种协议。

Released under the MIT License.