前端网络知识笔记

142 阅读17分钟

一、OSI七层模型

OSI(Open System Interconnection) 是理想化的模型,将网络进行分层,其目的是将复杂的流程简单化,每一层都完成自己的事情,从而实现分而治之(专人干专事)。

1. 网络分层的含义

下层是为上层提供服务的。分层如下:

  • 应用层
      1. 应用层:用户最终使用的接口 微信、qq、网页等
      1. 表示层:怎么去把数据进行描述、压缩
      1. 回话层:建立会话和管理会话的
    1. 传输层:把数据传递给对方,怎么传,丢啦要不要重新传递
    1. 网络层:网络层就是寻址
  • 网络接口层
    • 6. 数据链路层:主要关心的是将两个设备连接起来连接数据
      1. 物理层:只关心如何传输数据, 传输的是0/1的比特流 => 合并表示为四层:应用层、传输层、网络层、网络接口层 image.png
  • 报文:引用层 + 数据
  • 数据段:传输层 + 数据 + 端口号
  • 数据包:网络层 + 数据 + 端口号 + ip地址
  • 数据帧:链路层 + 数据 + 端口号 + ip地址 + mac地址

2. 地址

通讯是通过ip地址查找对应的mac来进行通讯的。IP地址是可变的(类似我们收件地址) MAC地址是不可变的。

  • IP地址
    • IPV4: IP地址的第四个版本,最大值为42亿个
    • IPV6: aaaa-aaaa-aaaa-aaaa-aaaa-aaaa-aaaa-aaaa
    • ip地址不是固定的
  • MAC地址
    • MAC地址原则是是唯一的,每一个网卡都会有一个mac地址

3. 物理设备

  • 物理层
    • 常见设备:光纤、同轴电缆、网线、中继器(局域网)
    • 物理层就是只关心怎么传输的,比较傻,通过多口的中继器/集线器给连接在这个局域网中的所以设备广播数据消息,不安全
  • 数据链路层
    • 常见设备:交换机(局域网)
    • 交换机会记录每个端口连接的设备的mac地址,通讯时通过这个mac地址直接找到对应的设备,而不是广播的方式。
  • 网络层
    • 常见设备:路由器(广域网)冲当网关
    • 默认两个不同的网络,是不能相互通讯的,想让两个不同的区域的设备通讯,需要经历网关。
    • 路由器相比交换机,有wan口就可以充当网关进行上网,没有wan口的路由器可以看成是交换机。 image.png

4. TCP/IP参考模型

  • 什么是协议?
    • 协议就是约定的规范(在7层模型中只有三层以上的才能称之为协议)
    • 协议分类:
      • 应用层协议:HTTP协议、DNS协议、DHCP协议
      • 传输层协议:TCP协议、UDP协议
      • 网络层协议:IP协议、ARP协议
  • ARP协议
    • 地址转换协议,核心价值在于将IP地址转化为mac地址 image.png image.png
  • DHCP协议
    • 动态主机配置协议Dynamic Host Configuration Protocol
    • 通过DHCP自动获取网络配置信息, 我们无需手动配置IP地址
  • DNS协议 (应用层)
    • DNS 是Domain Name System的缩写,DNS服务器进行域名和与之对应的IP地址转换的服务器
    • DNS会对IP及域名进行缓存,采用的是udp(无连接)访问。
    • 特征:
      • DNS中保存着一张域名于对应的ip地址的表
      • 一个域名对应一个IP地址。一个IP地址可以对应多个域名
    • gTLD: generic Top-Level DNS Server 顶级域名服务器 为所有 .com、.net......后缀做顶级域名解析的服务器
    • 域名层级:
      • 顶级域名:.cn、
      • 二级域名:.com.cn
      • 三级域名:www.zf.com.cn 有多少个点,就是多少级域名
    • 访问过程:当访问zf.com.cn
      • 操作系统里会对DNS解析结果做缓存,如果缓存中有就直接返回IP地址
      • 查找C:\WINDOWS\system32\drivers\etc\hosts,如果有就直接返沪IP地址
      • 没有就通过DNS服务器查找离自己最近的根服务器,通过根服务器找到.cn服务器,将ip返回给DNS服务器
      • DNS服务器会继续向此IP发送请求,去查找对应.cn下.com对应的IP...
      • 获取最终的ip地址,缓存到DNS服务器上 image.png

5. TCP和UDP

这两个协议都在传输层,常说的TCP是面向连接的,而UDP是面向无连接的。

  • TCP

    • tcp 传输控制协议(Transimision Control Protocal)可靠、面向连接的协议,传输效率低(在不可靠的IP层上建立可靠的传输层)。TCP提供全双工服务,即数据可在同一时间双向传播。
    • TCP数据格式 image.png
      • 源端口号、目标端口号,分别指代的是发送方随机端口、目标端对应的端口
      • 序列号:32位序列号是用于对数据包进行标记、方便重组
      • 4位首部长度:单位是字节,4位最大能表示15,所以头部长度最大位60
      • URG:紧急信号
      • ACK:确认信号
      • PSH:应该从TCP缓冲区读走数据
      • RST:断开重新连接
      • SYN:建立连接
      • FIN:表示要断开连接
      • 窗口大小:当前网络通畅时将这个窗口值变大加快传输速度,当网络不稳定时减少这个值。在tcp中起到流量控制作用。
      • 检验和:用来做差错控制,看传输的报文段是否损坏
      • 紧急指针:用来发送紧急数据使用
      • 注意:TCP对数据进行分段打包传输,对每个数据包编号控制顺序
  • TCP抓包

    • client.js
      const net = require('net');
      const socket = new net.Socket();
      socket.connect(8080, 'localhost'); // 客户端连接8080的服务端端口
      socket.on('connect', function(data){
          socket.write('connect server')
          socket.end()
      });
      socket.on('data', function(data){
          console.log(data.toString())
      });
      socket.on('error', function(error){
          console.log(error)
      });
      
    • server.js
      const net = require('net');
      const server = net.createServer(function(socket){
          socket.on('data', function(data){
              socket.write('server:hello')
          });
          socket.on('end', function(data){
              console.log('客户端关闭')
          });
      });
      socket.on('error', function(error){
          console.log(error)
      });
      socket.listen(8080) // 服务端启动监听8080端口
      
      image.png
    • 三次握手 image.png image.png
      • 我能主动和你打电话吗? SYN
      • 当然可以啊!那我也能给你打电话吧? ACK、SYN
      • 可以的呢,建立连接成功 ACK
      1. 三次握手是由于TCP是全双工的通讯服务,需要双方都确定可以相互发送和请求数据;
      2. 第二次握手,将请求连接的应答和确认双向通讯的连接建立一次发送回去;
    • 数据传输 image.png image.png
    • 四次挥手 image.png image.png
      • 我要挂掉电话了哈? FIN
      • 好的,我知道了 ACK
      • 传输完之前正在传输的数据,然后通知,数据传输完毕,可以关闭连接了 FIN
      • ok,断开连接 ACK
      1. 这里的中间两次挥不能合并为一次,是因为在当时可能还有之前的数据没有传输完毕,所有必能直接通知关闭连接,需要等确认数据传输完毕之后再通知关闭连接
      2. 为了防止最后的ACK丢失,发送ACK后需要等待一段时间,因为如果丢包了服务端需要重新发送FIN包,如果客户端已经closed,那么服务端会将结果解析成错误。从而在高并发非长连接的场景下会有大量端口被占用。
  • UDP

    • udp用户数据报文协议(User Datagram Protocol,是一个无连接、不保证可靠性的传输层协议)。
    • UDP发出请求后,不考虑对方是否能接收到、内容是否完整、顺序是否正确。收到数据后也不会进行通知
    • 首部结构简单,在数据传输时能实现最小的开销
    • 使用场景:DHCP协议、DNS协议、QUIC协议等(处理速度快,可以丢包的情况)
    • TCP数据格式: image.png
  • UDP抓包

    • client.js
      const dgram = require('dgram');
      const socket = dgram.createSocket('udp4');
      socket.on('message', function(msg, rinfo){
          console.log(msg.toString())
          console.log(rinfo)
      });
      socket.send(Buffer.from('hello world'), 0, 5, 41234, 'localhost', function(err, bytes){
          console.log('发送啦%d个字节', bytes)
      });
      socket.on('error', function(error){
          console.log(error)
      });
      
    • server.js
      const dgram = require('dgram');
      const socket = dgram.createSocket('udp4');
      socket.on('message', function(msg, rinfo){
          console.log(msg.toString())
          console.log(rinfo)
          console.send(msg, 0, msg.length, rinfo.port, rinfo.address)
      });
      socket.bind(41234, 'localhost')
      

    image.png

  • 滑动窗口

    • 滑动窗口:TCP是全双工的,所以发送端有发送端缓存区,接收端有接收端缓存区,要发送的数据都放到发送中的缓存区,发送窗口(要被发送的数据)就是要发送缓存中的哪一部分数据。
    • 核心是流量控制:在建立连接时,接收端会告诉发送端自己的窗口大小(rwnd),每次接收端收到数据后都会再次确认(rwnd)大小,如果值为0,停止发送数据。(并发送窗口探测包,持续监测窗口大小) 控制发送方的频率
    • 发送数据的时候时乱序发送的,但是当我们收到某个包后,坑你之前的包还没有收到,此时需要等待前面序号的包到了才可以(对头阻塞)
    • 服务端会和客户端说明发送包的个数
    • 如果某个包丢了,那需要重新发送(超时重传 RTO)
    • 当接受方的缓存区收满了,整滑动窗口大小为0,不发生数据,然后会每间隔一段时间,发送方会发送一个探测包,来询问能否调整滑动窗口大小。或者是上层协议消耗掉了接受放的数据,接受方的缓存区有空闲了,接收方也会主动通知发送方调整窗口,继续发送数据。
  • 粘包算法

    • nagle算法的基本定义是任意时刻,最多只能有一个未被确认的小段(TCP内部控制)
    • Cork算法:当达到MSS(Maximum Segment Size)值时统一进行发送(此值就是帧的大小 - ip头 - tcp头=1460个字节)理论值
  • TCP用塞处理
    假设接受窗口大小是无限的,接受到数据后就能发送ack包,那么传输数据主要依赖于网络带宽,带宽的大小是有限的

    • tcp常见的阻塞问题
      • 队头阻塞:TCP顺序问题,后面的包先到达需要等待前面的包返回之后才可以继续传输
      • 非长连接的情况下会有大量端口被占用:time-wait 客户端连接服务器最后不会立即断开,在高并发的短链接情况下,会出现端口全部专用。
      • 慢启动过程,非常的消耗性能
    • 拥塞处理:TCP维护一个拥塞窗口cwnd(congestion window)变量,在传输过程中没有阻塞就将此值增大。如果出现拥塞RTO(Retransmission Timeout)就将窗口减少
      • cwnd < ssthresh 使用慢开始算法
      • cwnd > ssthresh 使用拥塞避免算法
      • ROT时更新ssthresh值为当前窗口的一半,跟新cwnd = 1 image.pngw
      • 传输轮次:RTT(Round-trip Time) 从发送到确认信号的时间
      • cwnd控制发送窗口的大小
    • 快重传快恢复方式 image.png
      • 快重传,可能在发送的过程中出现丢包情况,此时不要立即回退到慢开始阶段,而是对已经收到的报文重复确认,如果确认次数达到3次,则立即进行快重传快恢复算法(减少超时重传机制的出现),降低重置cwnd的频率。

二、HTTP发展历程

  • 1990年HTTP/0.9为了便于服务器和客户端处理,采用来纯文本格式,只能使用GET请求。在响应请求之后会立即关闭连接
  • 1996年HTTP/1.0增强来0.9版本,引入了HTTP Header(头部)的概念,传输的数据不再仅限于文本,可以解析图片音乐等,增加了响应状态码和POST,HEAD等请求方法
  • 1999年广泛使用HTTP/1.1,正式标准,允许持久连接,允许响应数据分块,增加了缓存管理和控制,增加了PUT、DELETE等新的方法 (多个请求并发,管线化,http队头阻塞的问题)
  • 2015年HTTP/2,使用HPACK算法压缩头部,减少数据传输量。允许服务器主动向客户端推送数据,二进制协议可发起多个请求,使用时需要对请求加密通讯。(多路复用 1条tcp连接来通信数据)
  • 2018年HTTP/3基于UDP的QUIC协议

1. HTTP/1.1

HTTP是基于tcp传输层,半双工通讯的请求应答模式。http默认是无状态的(默认tcp是不能在没有应答完成后复用tcp通道继续发送消息,)。

  • tcp规范就是固定的组成结构

    • 请求行 响应行:主要的目的就是描述要做什么事,服务端告诉客户端OK来
    • 请求头 响应头:描述传输的数据内容,自定义我们的header(http中自己所做的规范)
    • 请求体 响应体:两者间传输的数据
  • 内容协商
    客户端和服务端进行协商处理,返回对应的结果。 image.png

  • 长连接
    TCP的连接和关闭,需要经历三次握手四次挥手等过程,非常耗时间,所以我们可以复用TCP创建的连接。在http/1.1中实现了长连接,会默认在请求和响应头中增加Connection:keep-alive/Connection:close。但是复用同一个tcp通道必须在一个请求响应结束之后,才能执行下一个请求操作,这就形成了阻塞,就是http/1.1中的对头阻塞,需要采用管线化的方式解决这个问题。

  • 管线化
    如果只创建一条TCP连接来进行数据的收发,就会变成“串行”模式,如果某个请求过慢就会发生阻塞问题(队头阻塞 Head-of-line blocking)。HTTP/1.1中采用来管线化的方式,对一个域名同时发起多个长连接实现并发。默认chrome为6个。

  • Cookie
    Set-Cookie/Cookie用户第一次访问服务器的时候,服务器会写入身份标识,下次再请求的时候会自动携带cookie。通过Cookie可以实现有状态的回话。(通常Cookie不要过大)

  • HTTP缓存

    • 强缓存:服务器会将数据和缓存规则一并返回,缓存规则信息包含在响应header中。 image.png 就是当客户端第一次访问服务端后,服务器说,在几点之前/多久之内 不要来找服务器了,直接在客户端的缓存中读取数据即可(在几点之前/多久之内不会再向服务器发送请求)。
      • Expires (http/1.0版本过时的参数,针对不支持http/1.1的服务做兼容方案)
      • Cache-Control: max-age=300 (缓存的最大有效时间)

      强制缓存存在有效期,缓存期内不会向服务器发送请求,超过时间后需要取服务端严重是否是最新版本。

    • 协商缓存:就是当强制缓存失效后会再次向服务器发起请求,服务器需要对比客户端的缓存的文件和服务器端端文件是否一致,如果一致则返回304状态码,如果文件更新了,就返回最新的文件数据。 image.png
      • 最后修改时间:last-modified/if-Modified-Since 在于以下两种情况下存在问题:
        • 最后修改时间是秒级的,一秒内修改多次无法监控
        • 最后修改时间变动了,但是内容没有发生变化
      • 指纹标识:Etag/If-None-Match
        • 摘要算法 md5 (不同的内容摘要的结果肯定不同,两个相同的内容摘要的结果肯定相同,无法通过最终的结果反推原内容,并且摘要的结果长度相同)。所以可以使用Etag/If-None-Match,如果签名一致则认为文件没有变化,可以使用缓存。
        • Cache-Control: no-chche(不缓存,但是缓存中有,每次都询问服务器,相当于跳过了协商缓存);Cache-Control: no-stare (真正的不缓存,压根就没有缓存)。
        • 当数据较大的时候,md5生产指纹比较消耗性能,会简单的使用弱指纹,可以用last-modified+文件长度,生产一个Etag指纹标识。

2. HTTP/2

  • 多路复用
  • 头部压缩
  • 服务端推送

3. HTTP/3

  • QUIC协议

三、HTTP中的优化

1. Timing

2. 优化

3. CDN

四、web安全之HTTPS

HTTP采用明文传输,中间人可以获取到明文数据(从而实现对数据的篡改)。这时候HTTPS就派上用场了。HTTPS是什么呢?HTTPS=HTTP+SSL/TLS,SSL是安全套接层(Secure Sokkets Layer)发展到V3时改名为TLS(传输层安全 Transport Layer Security),主要目的是提供数据的完整性和安全性,保证数据秘文传输并不会被篡改。 image.png

1. 数据完整性

  • 摘要算法
    • 把任意长度的数据压缩成固定的长度
    • 输入不同输出的结果发送剧烈的变化“雪崩效应”,相同的内容摘要后结果相同
    • 不能从结果反推输入

    我们可以在内容后面增加hash值进行传输,服务端收到后通过hash值来校验内容是否完整。数据是明文的不安全。

2. 数据加密

  • 对称加密
    加密和解密时使用的密钥都是同一个,通讯过程使用密匙加密后的密文传输。只有自己和网站才能揭秘 image.png 目前AES(Advanced Encryption Standard)、chacha20 为最常见大对称加密算法。
    唯一的密钥在传输的过程中可能会被中间人劫持而存在安全风险,不能确定这个公钥是谁发的。

  • 非对称加密(安全但是性能不好)
    非对称加密可以解决“密钥交换”的问题。非对称加密有两个密钥,公钥、私钥,所以称之为非对称。公钥加密私钥解密。 使用两套钥匙实现加密通讯,安全性高,但是性能不好,效率低,数据越大解密越复杂。 image.png 最常听到的非对称加密算法是RSA、ECC(子算法ECDHE用于密匙交换,ECDSA用于数字签名)(性能和安全略胜一筹)HTTPS中目前广泛使用ECC

  • 混合加密
    通讯刚开始的时候使用非对称算法,交换密钥。在客户端生成会话密钥后传送给服务端,后续通讯采用对称加密的方式 image.png 这里还并不安全,还涉及到中间人攻击(指攻击者与通讯的两端分别建立独立的联系,并交换其收到的数据) image.png

  • 数字证书和CA
    因为谁都可以发布公钥,所以我们需要验证对方身份。防止中间人攻击 image.png 客户端会判断有效期、颁发者、证书是否被修改及证书是否被吊销。每份签发证书都可以根据验证链查找到对应的根证书,操作系统、浏览器会在本地存储权威机构的根证书,利用本地根证书可以对对应机构签发证书完成来源验证。

    • 加密:对传输的数据进行加密
    • 数据一致性:保证传输过程中数据不会被篡改
    • 身份认证:确认对方的真实身份 image.png

3. HTTPS过程解析

  • 第一阶段
    • 客户端会发送 handshake Prootocol: client hello
      • Cipher Suites 密钥交换算法 + 签名算法 + 对称加密算法 + 摘要算法 (套件列表)
      • Random 客户端随机数
      • Version:TLS 1.2
    • 服务端会发送 handshake Prootocol: server hello
      • Version:TLS 1.2
      • Random 客户端随机数
      • Cipher Suites: 选择的套件

    双方选择TLS版本,确定加密算法,生产两个随机数

  • 第二阶段
    • 服务端发送证书 certificate
    • 服务端发送ECDHE参数,服务端Hello完成
      • Server Key Exchange
      • Server Hello Done
    • 客户端发送ECDHE参数,以后使用密钥进行通讯吧,加密握手消息发送给对方
      • Clent Key Exchange
      • change Cipher Spec
      • Encrypted HadnleShake Message
    • 服务端发送会话凭证,以后使用密钥进行通讯吧,加密握手消息发送给对方
      • new Session Ticket
      • change Cipher Spec
      • Encrypted HadnleShake Message image.png