step1 前言 & 课程介绍
目标:能够初步理解计算机网络中的各类概念,能够在实际工作中解决网络问题。
课程介绍:
- 建立对计算机网络的整体认识。
- 建立对网路协议分层的认知。
- 分析HTTP1、2、3的关系
- 介绍CDN运行的基本原理
- 了解网络安全的最基本原则
step2 蟹堡王帝国
三步走战略:通信网络的重要性。
蟹堡王外卖:
- 问题:章鱼哥一对一服务
单线程
,导致在客户较多时造成饥饿现象。 - 解决方法:传真的发明,讲服务端和客户端分离,服务端负责接受订单和派送外卖,客户端负责发送请求。
(C/S架构)
。
分店阶段:
- 问题1:客户太多了,单个服务端无法满足客户的请求。
- 解决方法:开拓新的服务端
分散单个服务端的压力
- 问题2:使用客户的范围越来越多,新的客户群体所在范围距离初始服务端过远,建造传真线路成本过高。
- 解决方法:各地开设的新的服务端互相连接
建立初始的网络
,将以原始服务端作为核心单核模式
转换为将所有服务端作为核心多核模式
。 - 问题3:不同的地区,客户端请求的密度不同。
- 解决方法:在客户端请求密度较大的区域开设小的服务端,缓解区域内的高密度请求
类似于菜鸟驿站等
,密度较小的区域则将服务端转发的区域面积扩大。
全国分店:
- 问题: 如果客户端想要覆盖全国,所有的客户端指向服务端,就会出现大量的重复线路
- 解决方法:设立小的服务端转发大的服务端的请求,根据客户端的密度来进行适配
路由器
。
总结:自顶向下的讲述了计算机网路的发展流程,从最开始的单服务端-多客户端
逐渐发展,客户端的请求量越来越多以及网络的覆盖范围越来越大导致了服务端必然增多诞生了更多的服务端节点
而在发展过程中,为了节约成本获取最大效益,逐渐进化出来服务端-转发节点-客户端
的网络结构,也就是对应着我们服务器-路由器-客户端这一结构。
step3 网络基础
网络组成部分
- 主机: 客户端/服务端
- 路由器:小范围节点
- 网络协议
http/tcp
: 统一格式
网络结构: 网络的网络
- 比奇堡和小区的网络:本地网络
- 北京和上海分店+比奇堡:本地网络节点的网络
- 全国通信网络:本地网络的网路
电路交换 & 分组交换
电路交换:1 to 1
分组交换:1 to n
通过设立每组的交换上线以及多个分组,成功建立
n to n
映射,实现网络布局,即:网络 = 网络的网络。
网络分层
- 物理层
- 链路层
- 网络层
- 运输层
- 应用层
每一层对于自身层级都有封装,这些封装上一层来说都是黑盒的,对于下一层调用者来说,无需关心下一层出现的问题。
协议
协议的存在依赖于连接
协议定义了两个通信的端口之间交换数据的格式以及顺序。
标头和载荷
- 标头记录了两个端口的信息以及传递数据所需要的协议识别信息。
- 载荷负载着传递的数据内容
HTTP协议示例
总结 :报文 = 链路层头+IP协议的头部+TCP协议头部+HTTP协议头部+HTTP的正文
TCP协议格式
在HTTP协议1.1以及之前的版本中
头部
和载荷
是通过两个换行符和回车符进行划分的,但是TCP协议和IP协议并不是。
小结
- 网络组成部分:主机、路由器、交换机等组成
- 网路结构:网络的网络
- 信息交换方式:电路交换和分组交换
- 网络分层:分清职责,物理层、链路层、网络层、运输层和应用层
- 网络协议:标头和载荷
step4 Web中的网络
HTTP协议
- 红色部分为请求
- 第一行:
- 请求的方法
get
- 资源路径
/
- Http版本
HTTP/1.1
- 请求的方法
- 其他行:
- 均为头部
- 头部使用
:
进行分割,采用的Key:Value
形式,但是注意Value
和:
之间有空格分割,类似于CSS
里面的语法。 - 左边为头部名称,右边为正文
- 第一行:
- 蓝色部分为响应
- 第一行:
- 被称为状态行
- 包含HTTP版本信息
HTTP/1.1
,状态码200
,状态信息OK
。
- 其他行:
- 均为头部
- 包含HTML文档
- 使用
:
分割头部名称和正文,分割采取的格式与红色部分相同。
- 第一行:
总结:与TCP协议相比,HTML协议的可读性更高,组成更为简单,更易让人理解,但是相对于计算机来说,解读难度更大。
HTTP连接模型
HTTP使用的是请求——响应模型
request--response
,导致只有服务端返回了上一次请求的响应,才能再次发送请求,这样导致了HTTP协议里一条线路的内容无法进行复用,网络资源利用率极低。例如Cookie就会发送很多次
- 第一个模型是HTTP/1.0的连接模型,默认为短连接,特点为:
- 服务端一次只能接受一次请求。
- 客户端只有在接收到上一次请求的响应,才能再次发送请求。
- 每一次连接在经过客户端发出、服务端返回之后都会被销毁。
-
总结:效率十分低下,极其浪费网络资源,请求体非常臃肿。
- 第二个模型是在HTTP/1.1中,只要不声明连接方式为短连接,默认为持久连接,特点为:
- 在执行完一次请求和响应后,连接并不会被直接销毁,而是会持续一段时间,等待下一次请求的发出,空闲一定时间才会销毁。
- 只有上一次的请求返回响应后,客户端才能再次发送请求。
-
*总结: 保持一段时间的连接实现连接重用,遇到响应时间长的请求会触发队头堵塞
- 第三个模型是HTTP管线模型,客户端可以同时发送多个请求,然后逐个响应。
- 但是基本没有浏览器使用这种模型。
- 无法解决队头堵塞的问题
- 会导致一定的安全性问题
对于队头堵塞问题,HTTP/1.1采用了同时建立多个HTTP连接,将请求封装在多个HTTP连接上,这样可以缓解队头堵塞的问题,但是成本巨大
对于客户端和服务端来说,用户的带宽是固定的,HTTP连接数量越多,单个连接分到的网络资源越少,而HTTP连接的数量也不是无限的,通常来说浏览器会限制每个域名下的HTTP连接的数量,通常是6个。
HTTP 1.1:无法实现多路复用
如果客户端将两个请求交错发送,那么服务器将无法分辨不同请求的内容,返回的响应无法满足请求需求。
HTTP2:帧
HTTP 2
中将多个HTTP请求封装到一个个帧
里面,每个帧可以携带来自不同HTTP连接的数据,这样可以保证HTTP建立多个连接的同时,每个数据包都可以标识自己属于哪个请求。进而实现HTTP多路复用。
注意,这种方式和链路层的帧不同,但是工作原理类似。
帧的结构
- 前三个字节是帧的长度
- 第四个字节是帧的类型
- 第五个字节会根据帧的类型携带不同的信息,用于传递当前帧的一些状态
- 第六个字节第一位是保留位,后面的31位代表着帧所属流的id
- 再后面为帧的载荷
总结:通过这种结构的帧,可以知道每个帧所属的流,进而能够判断每个帧的载荷属于哪个请求,最后进行拼接返回响应。
HTTP2:帧带来的额外好处
帧
不仅缓解了HTTP连接中队头堵塞的问题,还带来了如下的额外好处:
- 调整响应传输的优先级
- 头部压缩
- Server Push
HTTP2:TCP上的队头堵塞
例如上图,客户端向服务端发送四个TCP包,包含的内容如上所示,但是如果TCP包1丢包了,由于TCP的丢包重传机制,那么服务器将会收到TCP包1丢失的信息,且客户端再次向向服务端发送请求,尽管丢失的TCP包1与后续传输的包内存储的数据并无关系。
在这个例子中,由于TCP协议对上层数据缺乏必要的信息,导致TCP包1造成了队头堵塞
HTTP2:3 RTT启动
在TCP和TLS
层面,要启动一个HTTPS
连接,需要建立三个RTT
:
- TCP建立连接需要一个RTT
- TLS建立连接需要两个RTT
- TLS1.2以下需要两个RTT,1.3以上可以首次实现一个RTT二次连接
这样的连接方式会造成较大的延迟,以及TCP上造成的堵塞都无法被解决,那就建立一个新的协议来讲解决这些问题-->QUIC
QUIC
QUIC 将原有的TLS作为自身的一部分,解决了HTTP与TLS之间连接需要互相握手的问题,又吸取了HTTP2中流的概念,在QUIC中建立互相独立的流,进而解决了原理TCP中对头堵塞的问题,同时引入了新的机制。可以实现首次连接 1 RTT,后续连接0 RTT的特性,极大的加快了连接速度。
- Quick UDP Internet Connection
- 现存网络设备对TCP和UDP支持已经僵化
- UDP不靠谱但是QUIC靠谱
- QUIC可以为除HTTP协议以外的应用层协议提供支持。
HTTP协议回顾
HTTP协议中:
- 请求的第一行为起始行,响应的第一行为状态行。
- 请求和响应从第二行开始到第一空行为止均为头部。
- 第一空行之后的部分为正文 HTTP/1.0的数据连接为短连接模型,这种模型的效率极低,在HTTP/1.1中改为了不关闭连接。 HTTP/2中,使用帧实现了多路复用、头部压缩、Server Push等功能,大幅缓解了HTTP队头堵塞的问题,但是不能解决TCP连接的队头堵塞问题。 HTTP/3使用了基于UDP重新设计的QUIC协议,避免了TCP中的队头堵塞,并将TSL协议内置进QUIC,进一步降低HTTP握手延迟,可以实现首次1 RTT,二次0 RTT的连接。
CDN
为了分散单点服务器所承受的大量请求同时防止单点服务器出现问题导致网络瘫痪,CDNContent Delivery Network
内容分发网络 为了降低网络的延迟而被设计出。CDN服务器可以将从源服务器所获取的内容以自身为中心分发给区域内的客户端,极大的降低传输延迟。
CDN:DNS劫持
- 域名解析一般由网站自己处理
- 要加速的域名则重定向到CDN厂商的域名解析服务处理
- CDN厂商根据来源确定最近的CDN服务器的IP
- 用户直接访问最近的CDN服务器
访问一个域名的流程:
- 浏览器查询此域名所对应的IP地址,向上一层DNS服务器发送查询请求。
- 上层DNS查询后将域名交给域名对应的域名解析服务器
- 域名解析服务器发现该域名是一个CDN的加速域名,没有返回IP,而是返回一个新的DNS地址,该DNS地址是CDN管理的。
- 本地的DNS服务器向CDN的DNS发送请求,CDN根据用户IP发现距离用户最近的CDN服务器,并且返回该服务器的地址。
- 浏览器最终和CDN管理的DNS服务器返回的ip地址进行连接 给大家看看逻辑结构图(虽然有点潦草):
那么如何选择CDN服务器呢?
CDN:近了,近了嘛?
策略:根据DNS查询来源IP的地理位置确定最近的CDN服务器。 但是选择最近的CDN服务器并不一定最好,因为每次路由器的跳转都会加大延迟,而几十千米的传播延迟对于跳转来说显然更短。
除此以外,用户访问的负载等等都会影响用户最终访问的延迟。
CDN:地主家也没有余粮了
对于一些视频网站,如果在全国所有的CDN服务器上部署拷贝,成本将会非常巨大,因此大部分站点都会使用一些策略来保证大部分的用户的使用体验且降低成本。即只在CDN服务器维护部分内容,但这部分内容可以满足大部分用户的使用需求。
- 拉策略
- 默认情况下什么都不做
- 有需要了之后先在仓库查询,如果有就直接给,没有就从总服务器发起请求,然后拷贝到当前服务器上
- 每隔一段时间清除CDN服务器上最近使用/使用最少的数据
- 推策略
- 在知道即将需要的数据后,所有服务器都负载该数据
WebSocket
与HTTP相比有以下特点:
- 有状态的持久连接
- 服务端而已主动推送消息
- 用WebSocket发送消息延迟比HTTP低
WebSocket:示例
服务端代码
const { WebSocketServer } = require('ws');
const wss = new WebSocketServer({ port: 8080});
wss.on('connection',function connection(ws){
//有新连接时监听来自客户端的消息
ws.on('message',function message(data) {
//打印收到的信息,再把消息原封不动的发回给客户端
console.log(data);
ws.send(data);
});
});
客户端代码
const WebSocket - require('ws');
const ws = new WebSocket('ws://localhost:8080');
ws.on('opne',function open(){
//当建立连接时,向服务端的发送一条信息
ws.send('something');
});
ws.on('message', function message(data){
//当收到服务端的消息时,打印出来
console.log('recieved: %s',data);
});
WebSocket:升级
WebSocket:发送消息
对于链路层来说只需要关心Line-based text data这一消息
小结
- HTTP 1 2 3的演进历史
- CDN解决了HTTP协议之外的问题
- WebSocket从HTTP协议升级而来
step5 网络安全
明文和暗文
许多互联网信息交换无法通过明文进行,例如转账等等信息都需要经过加密才能够使用。
网络安全三要素
- 机密性:攻击者无法获取通信内容
- 完整性:攻击者对内容进行篡改时才能发现
- 身份验证:攻击者无法伪装成通信双方的任意一方与另一方通信
网络安全:对称加密和非对称加密
- 对称加密:加密、解密用相同的密钥
- 非堆成加密:加密、解密使用不同的密钥
公钥和私钥
,而且公钥加密只能用私钥解密,私钥加密只能用公钥解密
网络安全:密码散列函数哈希函数
- 输入:任意长度的内容
- 输出:固定长度的哈希值
- 性质:两个不同的输入使之经过密码散列函数后有相同的哈希值,在计算上是不可能的
网络安全:机密性
- 加密需要加密算法和密钥等信息
统称为秘密信息
- 网络是明文的,不安全
网络安全:完整性和身份验证
完整性和身份验证互相关联
- 客户端发送转账请求
- 服务端确认
- 请求真的是客户发送的
- 目标账户和转账金额没有被篡改
网络安全:如何实现机密性
- 已知:网络是明文的
- 如果双方可以通过明文通信商量出秘密信息,那么攻击者也可以
- 所以想要通过明文通信交换秘密信息,通信双方需要先有秘密信息
网络安全:如何实现完整性
- 密码散列函数性质:找到两个不同的输入使之经过密码散列函数后有相同的哈希值,在计算上是不可能的
Exp1:
- 有明文
m
,密码散列函数H
- 计算
H(m)
获得哈希值h
- 将m和h组合成新信息
m + h
- 将收方拆分
m + h
,重新计算H(m)
得h'
,对比h'
和h
Exp2:
- 有明文
m
,密码散列函数H
,以及一个密钥S
- 计算
H(m + s)
获得哈希值h
- 将
m
和h
组合成新信息m+h
- 接收方拆分
m + h
,重新计算H(m + s)
得h'
和h
- 所以想要实现完整性,通信双方需要先有秘密信息
网络安全:如何实现身份验证
- 签名:用于鉴别身份和防止伪造
- 非对称加密性质:加密、解密使用不同的密钥(公钥和私钥),而且公钥加密只能用私钥解密,私钥加密只能用公钥解密
- 客户端自己用私钥将信息进行加密,发送至服务端
- 服务端用公钥进行解密,获得原文
- 保证了机密性、完整性和身份验证
- 数字签名:对明文内容有哈希值使用私钥进行加密,验证者使用公钥进行验证
- 数字签名(指纹) = 私钥加密(密码散列函数(原文))
- 一般用于对公开内容(如含公钥的证书)进行数字签名,防止篡改
- 可信的人验证客户端的公钥
- 那么谁验证可信的人的公钥
- 根证书是证书链的尽头
- 验证的一连串证书称作证书链
- 分发证书、验证证书的基础设施称为PKI
Public Key Infrastructure
- 所以想要实现身份验证,通信双方协议先有秘密信息,即根证书中的公钥
网络安全: HTTPS
把HTTP的明文换成密文,再验证身份,即HTTPS
HTTPS = HTTP + TLS
TLS = 身份验证
+ 加解密
身份验证
靠PKI
服务端身份验证靠PKI,客户端身份验证靠HTTP协议
小结:
- 网络安全有三要素:机密性、完整性和身份验证
- 在没有提前交换秘密信息的前提下,无法在不安全的信道交换秘密信息
- PKI保证了普通用户不需要“面对面”和根证书机构交换根证书
- HTTPS使用PKI完成了除客户端身份验证以外的特性,客户端身份验证靠HTTP协议实现
PS:感觉字节网课老师讲的很生动形象,非常的通俗易懂,学习的很快~