计算机网络
五层网络模型
从上到下分别为:应用层、传输层、网络层、数据链路层、物理层。在发送消息时,消息从上到下进行打包,每一层会在上一层基础上加包,而接受消息时,从下到上进行解包,最终得到原始信息。 其中:
- 应用层主要面向互联网中的应用场景,比如网页、邮件、文件中心等等,它的代表协议有 http、smtp、pop3、ftp、DNS 等等
- 传输层主要面向传输过程,比如 TCP 协议是为了保证可靠的传输,而 UDP 协议则是一种无连接的广播,它们提供了不同的传输方式
- 网络层主要解决如何定位目标以及如何寻找最优路径的问题,比如 IP 等等
- 数据链路层的作用是将数据在一个子网(广播域)内有效传输,MAC地址、交换机都是属于该层的 5.物理层是要解决二进制数据到信号之间的互转问题,集线器、双绞线、同轴电缆等都是属于盖层的设备
网络组成部分
- 主机:客户端和服务端
- 路由器
- 网络协议
网络协议
- IP(Internet Protocol,互联网协议)
- TCP(Transmission Control Protocol,传输控制协议)
- UDP(User Datagram Protocol,用户数据报协议)
- DNS(Domain Name System,域名系统)
- HTTP(Hypertext Transfer Protocol,超文本传输协议)
- FTP(File Transfer Protocol,文件传输协议)
- SMTP(Simple Mail Transfer Protocol,简单邮件传输协议)
- ARP(Address Resolution Protocol,地址解析协议)
- ...
HTTP各版本差异
HTTP1.0
无法复用连接
HTTP1.0为每个请求单独新开一个TCP连接
由于每个请求都是独立的连接,因此会带来下面的问题:
- 连接的建立和销毁都会占用服务器和客户端的资源,造成内存资源的浪费
- 连接的建立和销毁都会消耗时间,造成响应时间的浪费
- 无法充分利用带宽,造成带宽资源的浪费
TCP协议的特点是「慢启动」,即一开始传输的数据量少,一段时间之后达到传输的峰值。而上面这种做法,会导致大量的请求在TCP达到传输峰值前就被销毁了
队头阻塞
HTTP1.1
长连接
为了解决HTTP1.0的问题,HTTP1.1默认开启长连接,即让同一个TCP连接服务于多个请求-响应。
在这种情况下,多次请求响应可以共享同一个TCP连接,这不仅减少了TCP的握手和挥手时间,同时可以充分利用TCP「慢启动」的特点,有效的利用带宽。
实际上,在HTTP1.0后期,虽然没有官方标准,但开发者们慢慢形成了一个共识:
只要请求头中包含Connection:keep-alive,就表示客户端希望开启长连接,希望服务器响应后不要关闭TCP连接。如果服务器认可这一行为,即可保持TCP连接。
当需要的时候,任何一方都可以关闭TCP连接
扩展知识
连接关闭的情况主要有三种:
- 客户端在某一次请求中设置了
Connection:close,服务器收到此请求后,响应结束立即关闭TCP
- 在没有请求时,客户端会不断对服务器进行心跳检测(一般每隔1秒)。一旦心跳检测停止,服务器立即关闭TCP
- 当客户端长时间没有新的请求到达服务器,服务器会主动关闭TCP。运维人员可以设置该时间。
由于一个TCP连接可以承载多次请求响应,并在一段时间内不会断开,因此这种连接称之为长连接。
管道化和队头阻塞
HTTP1.1允许在响应到达之前发送下一个请求,这样可以大幅缩减带宽限制时间
但这样做会存在队头阻塞的问题
由于多个请求使用的是同一个TCP连接,服务器必须按照请求到达的顺序进行响应
想一想为什么?
于是,导致了一些后发出的请求,无法在处理完成后响应,产生了等待的时间,而这段时间的带宽可能是空闲的,这就造成了带宽的浪费。
队头阻塞虽然发生在服务器,但这个问题的根源是客户端无法知晓服务器的响应是针对哪个请求的。
正是由于存在队头阻塞,我们常常使用下面的手段进行优化:
- 通过减少文件数量,从而减少队头阻塞的几率
- 通过开辟多个TCP连接,实现真正的、有缺陷的并行传输
浏览器会根据情况,为打开的页面自动开启TCP连接,对于同一个域名的连接最多6个
如果要突破这个限制,就需要把资源放到不同的域中
然而,管道化并非一个成功的模型,它带来的队头阻塞造成非常多的问题,所以现代浏览器默认是关闭这种模式的
HTTP2.0
二进制分帧
HTTP2.0可以允许以更小的单元传输数据,每个传输单元称之为帧,而每一个请求或响应的完整数据称之为流,每个流有自己的编号,每个帧会记录所属的流。
比如,服务器连续接到了客户端的两个请求,一个请求JS、一个请求CSS,两个文件如下:
function a(){}
function b(){}
.container{}
.list{}
最终形成的帧可能如下
可以看出,每个帧都带了一个头部,记录了流的ID,这样做就能够准确的知道这一帧数据是属于哪个流的。
这样就真正的解决了共享TCP连接时的队头阻塞问题,实现了真正的多路复用
不仅如此,由于传输时是以帧为单元传输的,无论是响应还是请求,都可以实现并发处理,即不同的传输可以交替进行。
由于进行了分帧,还可以设置传输优先级。
头部压缩
HTTP2.0之前,所有的消息头都是以字符的形式完整传输的
可实际上,大部分头部信息都有很多的重复
为了解决这一问题,HTTP2.0使用头部压缩来减少消息头的体积
对于两张表都没有的头部,则使用Huffman编码压缩后进行传输,同时添加到动态表中
服务器推
HTTP2.0允许在客户端没有主动请求的情况下,服务器预先把资源推送给客户端
当客户端后续需要请求该资源时,则自动从之前推送的资源中寻找
网络安全
三要素:
- 机密性:攻击者无法获知通信内容
- 完整性:攻击者对内容进行篡改时能被发现
- 身份验证:攻击者无法伪装成通信双方的任意一方与另一方通信
加密方式:
对称加密
常见算法:DES、3DES、TDEA、Blowfish、RC5、IDEA
优点:加密、解密速度快,适合对大数据量进行加密
缺点:在网络中需要分发密钥,增加了密钥被窃取的风险
非对称加密
常见算法:RSA、Rabin、DSA、ECC、Elgamal、D-H
优点:安全(私钥仅被一方保存,不用于网络传输)
缺点:仅能一方进行解密
摘要/哈希/散列
常见算法:MD4、MD5、SHA1
优点:密文占用空间小(定长的短字符串);难以被破解
缺点:无法解密
HTTPS
HTTPS = HTTP + TLS(Transport Layer Security,传输层安全性协议)
HTTPS(Hyper Text Transfer Protocol over SecureSocket Layer),建立在SSL协议之上的HTTP协议
TLS = 身份验证 + 加解密
服务端身份验证靠 PKI,客户端身份验证靠HTTP协议。