计网
计算机网络
相关点
TCP/IP网络模型
应用层(application)
最上层,应用软件都在应用层实现。
应用层专注于为用户提供应用功能,比如HTTP、DNS等传输层(Transport)
传输层有两个协议:TCP和UDP
TCP的全程叫 传输控制协议(Transmission Control Protocol) , 大部分使用的正是 TCP 传输层协议,比如 HTTP 应用层协议。 TCP比UDP多了很多特性,比如可靠传输、流量控制、拥塞控制等。UDP的全称叫 用户数据包协议(User Datagram Protocol)。 UDP简单到只负责发送数据包,不保证是否抵达。但实时性相对更好,传续效率高。UDP也可以实现可靠传输,把 TCP 达到特性在应用层实现。
应用层传输的数据可能很大,如果直接传输就不好控制,因此当传输层的数据包大小超过 MSS(TCP最大保本段长度) ,就要将数据包分块,这样即使途中有数据包丢失,只需要重新传送这一个分块。在 TCP 协议中,每个分块成为一个 TCP段(TCP Segment)
传输层携带端口,识别该报文发送给哪个应用
- 网络层(Network)
网络层负责实际的传输功能
网络层最常使用的IP 协议,IP 协议将传输层的报文作为数据部分,加上IP包头组成 IP 报文,如果 IP 报文大小超过MTU(一般为1500字节)就会再次进行分片,得到一个即将发送到网络的 IP 报文。
IP协议的寻址作用告诉我们去往下一个目的地该朝哪个方向走,路由则是根据[下一个目的地]选择路径。寻址更像导航,路由更像操作方向盘
- 网络接口层(Link)
在接收到 IP 报文后,交给 网络接口层在 IP 头部的前面加上 MAC 头部,并封装成数据帧发送到网络。
MAC 头部是以太网使用的额头不,包含接收方和发送方的 MAC地址等信息。通过 ARP 协议获取对方的 MAC 地址。
小结
- 应用层:负责向用户提供应用程序
- 传输层:对应用层数据进行分组和重组,并以TCP或UDP协议格式封装报文。
- 网络层:负责路由以及把分组报文发送给目标网络或主机。
- 链路层:负责封装和解封 IP 报文,发送和接收ARP/RARP报文等。
OSI七层模型为:应用层、表示层、会话层、传输层、网络层、数据链路层、物理层。由于复杂并没有广泛使用。
键入网址流程
todo…
HTTP
HTTP 是超文本传输协议,也就是H yper T ext T ransfer P rotocol
状态码
- 1xx:提示信息,表示正在处理
- 2xx:成功
- 3xx:重定向
- 4xx:客户端错误
- 5xx:服务器错误
HTTP 常见字段
Host字段:用来指定服务器域名Content-Type字段:用来指定请求或响应的数据类型Connection字段:用来指定是否为长连接
GET 和 POST
GET 方法就是安全且幂等的, 因为它是 [只读] 操作,可以对 GET 请求的数据做缓存,可以做到服务器本身上,也可以做到代理上(如Nginx),而且在浏览器中 GET请求可以保存为书签。POST因为要提交数据,所以是不安全的,且多次提交数据就会创建多个资源,所以不是幂等的。浏览器一般不会缓存 POST 请求,也不能把 POST 请求保存为书签。
HTTP 缓存
对于一些具有重复性的请求,可以对 [请求-响应] 的数据都 缓存在本地,那么下次直接读取,不必获取服务器响应。
缓存实现方式:强制缓存 和 协商缓存。
- 强制缓存:服务器在响应头中设置
Cache-Control字段,设置max-age或者Expires字段,浏览器会根据这些字段判断是否需要缓存。 - 协商缓存:基于
时间或标识来实现。 服务器在响应头中设置Last-Modified(这个相应资源的最后修改时间)或者Etag(唯一标识响应资源)字段,浏览器会根据这些字段判断是否需要缓存。 如果两个字段都有,Etag的优先级更高。
注:协商缓存这两个字段都需要配合强制缓存中 Cache-Control 字段来使用,只有在未能命中强制缓存的时候,才能发起带有协商缓存字段的请求。
HTTP 特性
HTTP/1.1无状态 和 明文传输 既是优点也是缺点
无状态表明服务器不会保存客户端的状态,服务器资源能利用更加高效。但缺点就是服务器没有记忆能力,每次请求都需要对身份进行确认。明文传输方便阅读,方便进行调试,但缺点是安全性低。
HTTP 的安全问题,可以用 HTTPS 的方式解决,通过引入 SSL/TLS 层使得在安全上达到了极致。
性能相关
HTTP 基于 TCP/IP ,并且使用了 [请求-应答] 的通信模式,所以性能的关键在于:
- 长连接
HTTP/1.0 默认不支持长连接,每一次请求都要新建 TCP连接,性能差,而 HTTP/1.1 提出了长连接,减少了重复简历连接的开销 - 管道网络传输
HTTP/1.1 默认支持管道网络传输,可以同时发送多个请求,减少请求等待时间。但服务器必须按照接收请求的顺序发送对这些管道请求的响应
这就有个问题:HTTP/1.1解决了请求的队头阻塞,但是没有解决响应的对头阻塞。
HTTP 与 HTTPS 区别
- HTTP 是超文本传输协议,信息明文传输,不安全。HTTPS 是 HTTP 的安全版本,在 TCP 和 HTTP 网络层之间加入了 SSL/TLS 安全协议,使得报文加密传输。
- HTTP建立连接相对简单, TCP 三次握手就可以;而 HTTPS 还需要进行 SSL/TLS 的握手过程。
- HTTP 默认端口
80, HTTPS 默认端口443。 - HTTPS协议要向 CA(证书权威机构) 申请数字证书,来保证服务器的身份是可信的。
HTTPS 解决 HTTP 风险
- 信息加密: 交互信息无法窃取
- 校验机制: 无法篡改通信内容
- 身份证书: 服务器端证书,证明真伪
解决方法
混合加密实现信息的机密性摘要算法实现完整性,为数据生成独一无二的 [指纹] ,用来校验数据完整性- 将服务器公钥放入
数字证书解决冒充
混合加密
HTTPS 采用 对称加密 和 非对称加密 结合的 [混合加密]
- 在通信建立前采用
非对称加密交换 [会话密钥] ,后续不再使用非对称加密 - 在通信过程中全部使用
对称加密的方式加密明文数据
采用 [混合加密] 原因:
对称加密只有一个密钥,运算速度快,密钥需保密,无法做到安全的交换非对称加密使用两个密钥:公钥和私钥,公钥可以任意分发而私钥保密,解决了交换问题但速度慢。
摘要算法 + 数字签名
为保证传输内容不被篡改,需对内容计算出一个 [指纹] ,然后同内容一起传输给对方;收到后先对内容计算一个 [指纹] ,然后跟发送方传输的 [指纹] 进行比较,如果不相同,则认为内容被篡改。
那么,摘要算法(哈希函数) 来计算出内容的哈希值,也就是 [指纹] ,哈希值是唯一的,且无法通过哈希值推导出内容
通过哈希算法可以确保内容不被篡改, 但是不能保证 [内容 + 哈希值] 不会被中间人替换,因为这里缺少对客户端收到的消息是否来源于服务端的证明。
计算机会用 非对称加密算法 解决。通过 [私钥加密,公钥解密] 的方式,确认消息身份,也就是 数字签名算法,加密的内容不是内容本身,而是 对内容的哈希值加密 。
数字证书
服务器把公钥注册到数字证书认证机构中, 数字证书认证机构会颁发一个数字证书 ,这个证书中包含了公钥,以及一些其他信息,比如服务器的域名,过期时间等。
客户端拿到服务器的数字证书使用CA的公钥确认服务器的数字证书真实性,从数字证书获取服务器公钥对报文加密后发送,服务器再用私钥进行解密。这样就安全了。
HTTP/1.1 相比 HTTP/1.0
改进
- 使用
长连接 - 支持 管道 网络传输,只要第一个请求发送了,不必等其回来,就可以发送第二个
瓶颈
- 请求/响应头未经压缩就发送,首部信息越多延迟越大
- 发送冗长的首部。每次发送相同的首部造成的浪费较多
- 服务器按请求的顺序响应,造成
响应对头阻塞 - 没有请求优先级控制
- 请求只能从客户端开始,服务器只能被动响应
HTTP/2 的优化
头部压缩
如果同时发出多个请求,他们的头是一样的或相似的,协议会帮助消除重复部分
基于HPACK算法:在客户端和服务器同时维护一张头部信息表,所有字段都会存入这个表,生成一个索引号,以后不会发送同样字段,只发送索引号,减少头部信息二进制格式
HTTP/2 不再像 HTTP/1.1 里纯文本的报文形式,全面采用二进制格式,头部信息和数据体都是二进制,并且统称为帧:头信息帧、数据帧。
这样对计算机非常友好,计算机不用解析,增加数据传输效率并发传输
引入 Stream 概念,多个 Stream复用在一条 TCP 连接上针对不同的 HTTP 请求用独一无二的 Stream ID 来区分,接收端可以通过 Stream ID有序组装 HTTP 消息,不同 Stream 的帧可以乱序发送,因此可以并发不同的 Stream, HTTP/2 可以并行交错地发送请求和响应服务器推送
HTTP/2 中服务器不再被动地响应,可以主动向客户端发送消息。
客户端和服务器双方都可以建立 Stream,客户端建立的是 奇数号,服务器建立的是偶数号。
HTTP/2的缺陷
解决了 HTTP/1 队头阻塞, 但响应对头阻塞问题仍然存在。
HTTP/2 是基于 TCP协议来传输数的, TCP 是字节流协议, TCP层必须保证收到的字节流是完整的且连续的,这样内核才会将缓冲区的数据返回给 HTTP 应用,那么当 [前1个字节数据] 没到达时, 后面收到的只能存放在内核缓冲区,等这1个字节数据到达时,内核才会返回给应用层,应用层才能处理。 这就是 HTTP/2 队头阻塞
TCP/IP
TCP 是 面向连接的、可靠的、基于字节流 的传输层通信协议。
TCP 头的格式
TCP 连接是需要客户端与服务端达成三个信息共识
- Socket:由 IP 地址和端口号组成
- 序列号:用来解决乱序问题
- 窗口大小:用来做流量控制
最大 TCP 连接数 = 客户端IP数 ✖ 客户端的端口数
UDP 和 TCP 有什么区别
UDP 协议非常简单,头部只有 8 个字节
- 源端口和目标端口号(各16位):告诉UDP发送给哪个进程
- 包长度(16位):保存了 UDP 首部长度和数据长度之和
- 校验和(16位):校验和为了提供可靠的 UDP 首部和数据而设计,防止收到在网络传送中受损的 UDP 包
区别
- 连接
- TCP 是
面向连接的,传输前需要建立连接 - UDP 不需要连接
- 服务对象
- TCP 是一对一两点服务
- UDP 支持一对一、一对多、多对多
- 拥塞控制、流量控制
- TCP 又拥塞控制和流量控制机制,保证数据传输安全性
- UDP 则没有,即使网络拥堵,也不会影响 UDP 发送速率
- 首部开销
- TCP 首部长度有一定开销,首部没有使用 [选项] 字段时是
20字节,如果使用会更长 - UDP 首部长度是固定的
8字节
- 分片
- TCP的数据大小超过
MSS,则会在传输层分片 - UDP 的数据大小超过
MTU,则会在网络层分片
TCP 三次握手
TCP 是面向连接的协议,所以使用 TCP 前必须建立连接,而 建立连接时通过三次握手进行的
- 客户端向服务器发送一个
SYN报文,该报文初始化首部的[序列号],同时把SYN标志位设置为1,表示发起连接。 - 服务器收到该报文后,如果允许连接,首先初始化自己的 [序列号] ,其次把 [确认应答号] 填入
客户端的序列号 + 1,接着把SYN和ACK标志位都设置为1,表示接受连接。 - 客户端收到服务器的报文后,初始化自己的 [确认应答号] ,然后把 [序列号] 填入
服务器的序列号 + 1,最后把ACK标志位设置为1,最后把报文发送给服务端,之后处于ESTABLISHED状态 - 服务端收到报文后,也进入
ESTABLISHED状态。
在三次握手过程中,第三次握手可以携带数据,前两次是不可以携带数据的
为什么是三次握手,不是两次、四次?
- 三次握手可以
阻止重复历史连接的初始化(主要原因) - 同步双方初始化序列号
- 避免资源浪费
TCP 四次挥手
- 客户端打算关闭连接,此时会发送一个 TCP 首部
FIN标志位为1的报文,即FIN报文,之后客户端进入FIN_WAIT_1状态 - 服务端收到该报文后,就向客户端发送
ACK应答报文,接收服务端进入CLOSE_WAIT状态 - 等服务端处理完后就向 客户端发送
FIN报文,即FIN报文,服务端进入LAST_ACK状态 - 客户端收到服务端
FIN报文后,回一个ACK应答报文,进入TIME_WAIT状态,服务端收到 ACK 应答后,就进入 CLOSE 状态,客户端等待 2MSL (报文最大生存时间) ,进入 CLOSED 状态
