OSI七层
OSI 模型把网络通信的工作分为 7 层,从下到上分别是应用层、表示层、会话层、传输层、网络层、数据链路层、物理层。
- 应用层:用户与计算机交互的接口
- 表示层:将逻辑语言(软件语言)转换为机器语言(二进制)。进行数据处理(编码解码,加密解密)
- 会话层:管理 (建立、维护、重连)传输的每一种数据(流量) 的通信会话
- 传输层:负责向两台主机进程之间的通信提供通用的数据传输服务(TCP/UDP)
- 网络层:数据路由(决定数据在网络中的路径)
- 数据链路层:管理相邻结点之间的数据通信
- 物理层:实现相邻计算机节点之间比特流的透明传送
应用层 详解
HTTP
HTTP 是一个在计算机世界里专门在「两点」之间「传输」文字、图片、音频、视频等「超文本」数据的「约定和规范」
概述
HTTP 是一个在计算机中专门在两点 之间传输文字、图片、音频、视频等「超文本」数据的「约定和规范」。
可以说HTTP是用于从互联网服务器传输超文本到本地浏览器or两台服务器之间互相传输超文本的协议
HTTP优缺点
优点
简单、
报文格式:
header + body,头部信息是key-value存储,易于理解灵活、易于扩展
请求方法、URL、状态码、头字段等不是固定的几个,允许开发者自定义和扩展
应用广泛、跨平台
缺点
无状态:
好处:不需要使用额外空间来记录状态信息,减轻了服务器负担
坏处:不记忆状态,服务器无法判断用户身份。
完成关联操作会很麻烦,不知道那些请求是相互关联的
如登录–加购–下单–支付这一系列步骤,是同一个用户来操作的,每次请求都需要获取一次身份信息
可以使用cookie来解决,cookie是包含用户信息的本地浏览器的文件,需要保存用户的省份信息的话,响应给浏览器一个cookie,后面再请求这个网站,将请求信息和cookie一起发送,服务器就能辨识用户的身份
明文传输:明文传输虽然方便阅读,但是将所有信息裸露在外,容易被窃取
不安全:
- 通信使用明文,信息可能被窃取
- 不验证对方身份,可能遇到假冒网站
- 无法证明报文的完整性,可能报文被恶意修改,植入广告
HTTP常见状态码
状态码类别
| 类别 | 含义 |
|---|---|
| 1XX | 提示信息,服务器收到了请求,需要用户继续执行操作 |
| 2XX | 成功,请求被接收并处理完成 |
| 3XX | 重定向,资源位置发生变动,需要客户端重写发送请求 |
| 4XX | 客户端错误,请求报文错误,无法处理 |
| 5XX | 服务器错误,请求时,服务器内部发生错误 |
常见状态码
- 200:请求成功 ,非HEAD请求,服务器返回的响应头会有body数据
- 204:与200相同,但费HEAD请求,响应头没有body数据
- 301:永久重定向,请求的资源不存在,需要使用新的URL重新访问
- 302:临时重定向,请求的资源在,暂时需要使用其他URL访问
- 304:缓存重定向,不跳转,重定向已存在的缓存文件
- 400:表示客户端请求的报文有错误,没有具体定位错误
- 403:服务器禁止访问资源,不是请求错误
- 404:请求的资源不存在 or 找不到
- 500:服务器内部发生错误,但没有具体定位
- 501:请求的功能不支持
- 502:服务器本身正常,访问后端服务器发生错误
- 503:服务器很忙,暂时无法响应
HTTP与HTTPS的区别
- HTTP:超文本传输协议,明文传输,存在安全问题。HTTPS解决了HTTP的缺点,能够加密传输<-在TCP和HTTP之间加入了SSL/TLS协议
- HTTP建立连接相对简单:TCP三次握手之后就可以进行报文传输。HTTPS在三次握手后,还需进行SSL/TLS的握手,才能进行报文传输
- HTTP是80端口;HTTPS是443端口
- HTTPS需要申请数字证书,来保证服务器的身份是可信的
- HTTP协议的URL以
http://开始,HTTPS的URL以https://开始
HTTP存在的问题,以及HTTPS是如何解决的?
HTTP是明文传输,所以存在一些安全问题
- 窃听风险:通信链路上可以获取通信内容
- 篡改风险:强制植入广告、病毒
- 冒充风险:假冒网购平台
HTTPS在TCP与HTTP之间加入了SSL/TLS协议,解决了这些问题

HTTPS 是如何解决上面的三个风险的?
- 混合加密解决了窃听风险
- 摘要算法解决了篡改风险
- 数字证书,解决了冒充风险
HTTP 1.0、HTTP 1.1及HTTP 2.0的主要区别
短连接:每次请求都建立TCP连接,无法复用
长连接:建立连接后保持连接,可以被多个请求复用
http1.0:每一次请求都会建立一个TCP连接,请求结束就释放连接,频繁的三次握手、四次挥手,性能开销大
http1.1:引入了长连接(keep-alive) ,在一个TCP连接上可以传送多个请求和响应,减少了建立和关闭连接带来的开销与延迟。服务端按请求的顺序,排队处理,队头请求超时,后续的请求就会阻塞(队头阻塞);这样保证了客户端收到的数据与请求是对应的。响应头与请求头对应起来。
http2.0:
http2.0是基于HTTPS协议的
- 二进制格式: http1是纯文本的报文,http2是二进制的报文,不用像http1在接收后将超文本通过Base64转为字符串,到TCP层再转为二进制。
- 多路复用:可以在一个请求中并发多个请求和响应,不用像http1.1一样按请求的顺序来响应,没有 [队头阻塞] 的问题,降低了延迟,提高了连接的利用率
- 压缩头部:多个请求如果请求头一样,http2会自动去掉这些请求的重复部分,数据体积变小,传输速度变快,在客户端和服务端各维护一个header信息表,报文都会存入该表,生成一个索引,后续只发送索引就可以,提高了速度
- 服务端推送:服务端可以主动向客户端push消息(如加载网页的css、js等,提前发送给客户端,减少延迟)
描述一次完整的HTTP请求过程
客户端要访问www.baidu.com,浏览器发起一个DNS请求,如果本地缓存没有的话,就向根域名服务器查询,根服务器返回com服务器的信息,向com域名服务器查询,返回一个baidu.com服务器的信息,再向baidu.com域名服务器查询,最后返回地址:14.215.177.38,顺利进入百度首页
HTTPS
HTTPS加密过程
HTTPS使用混合加密的方式(加密对称与非加密对称混合使用)
对称加密与非对称加密
对称加密
对称的密钥
加密和解密使用同一个密钥,加密速度快,效率高 。但是不能安全的发送密钥。
非对称加密
一对非对称的密钥
- 公钥:自己的锁,可以随意让他人使用
- 私钥:打开自己锁的钥匙,B使用A的公钥加密文件,发送给A,A使用私钥来打开这个文件

公钥和私钥都可以进行加密和解密
一般客户端使用公钥,服务端使用私钥
非对称加密的过程:
- 客户端使用公钥将明文进行加密形成密文,发送给服务端
- 服务端收到密文,使用私钥进行解密,得到明文
- 将收到明文的确认信息发给客户端
- 客户端可以使用对称加密来传递信息了
非对称加密不需要对方发送解密的密钥,非常安全,但是比对称加密就要慢很多
DNS 域名解析过程
DNS( Domain Name System) 域名系统
访问网页,输入域名,通过DNS解析得到IP地址,从而访问
DNS通过UDP传输
域名的层级
- 根域名:
.root或.一般省略 - 顶级域名:
.com、.cn、.edu、.org… - 二级域名:
www.bilibili.com中的bilibili - 三级域名:
yahoo.co.uk中的yahoo
解析过程

- 客户端访问www.baidu.com,发起DNS解析请求。先查询浏览器中的DNS缓存,如果有且没有过期(缓存1分钟,容量1000条),解析结束
- 浏览器搜索操作系统中的DNS缓存
- 发送到本地DNS服务器上,查询缓存记录,如果有记录直接返回
- 本地DNS服务器向根服务器发送DNS请求,没查到就告诉本地DNS服务器该去哪个服务器查(
.com域名服务器) - 本地DNS服务器向 .com服务器发送DNS请求,没查到就告诉本地DNS服务器去哪找
- 本地DNS服务器向
baidu.com域名服务器发送DNS请求,baidu.com域名服务器在缓存中发现映射关系,返回IP给本地DNS服务器 - 本地DNS服务器将IP与域名的映射保存在缓存中,返回IP给客户端
查询方式
递归查询
只发送一次请求,等待返回结果就可以
客户端->本地DNS服务器->根域名服务器->.com域名服务器->baidu.com域名服务器
客户端<-本地DNS服务器<-根域名服务器<-.com域名服务器<-baidu.com域名服务器
迭代查询
经过多次请求,得到结果

传输层 详解
UDP

- 目标端口号:接收进程的端口
- 源端口号:发送进程的端口
- 包长度:保存 首部长度 与 数据长度 之和
- 校验和:设计可靠的UDP首部和数据
概述:
将数据、源端口、目的端口封装成数据包,不需要建立连接
每个数据报的大小限制在64K内
因无需连接,故是不可靠的
发送数据结束时不需要释放资源,速度快
TCP
概述
TCP是面向连接、可靠的、基于字节流的传输层通信协议。
- 面向连接:一对一,两台设备之间建立连接
- 可靠的:总能保证报文一定能送达接收方
- 基于字节流:数据是
没有大小限制的、有序的、如果先收到数据后面的字节,不会立即发送给对方,等待接收完毕,再丢弃重复的字节,最后发送出去完整不重复的数据。
TCP与UDP的区别
连接
TCP是面向连接的,就像打视频电话,需要先打通对方电话,等待对方有回应后才会跟对方继续说话,也就是一定要确认可以发信息以后才会把信息发出去。TCP上传任何东西都是可靠的,只要两台机器上建立起了连接,在本机上发送的数据就一定能传到对方的机器上。
UDP是无连接的;就像发邮件,只负责发送出去,不管对方有没有收到,所以UDP是不可靠的。
可靠性
- TCP传送数据可靠,但是消耗更多的资源,传送得比较慢。
- UDP传送数据不可靠,但是使用更少的资源,传送得快。
连接对象
- TCP只能是两台设备之间互相收发数据
- UDP可以一对一、一对多、多对多
拥塞控制、流量控制
- TCP有拥塞控制和流量控制机制
- UDP没有,网络拥堵也不会影响UDP的速率
传输的方式
- TCP是基于字节流传输,保证了数据的有序性和完整性
- UDP是按每个包发送,有大小限制,可能会有丢包、乱序的问题
应用场景
- TCP用于
FTP文件传输、HTTP/HTTPS - UDP用于DNS、SNMP、视频、音频、广播

UDP为什么没有首部长度?
- TCP有可变长的【选项】字段,UDP头部长度是固定的,不用专门使用一个字段来记录
TCP为什么没有包长度?
TCP和UDP是基于IP的,两个数据长度计算方法类似
TCP数据长度 = IP总长度 + IP 首部长度 + TCP 首部长度
TCP的数据长度可以直接计算出来,IP长度,TCP首部长度都是已知的,不用专门设置一个字段来存储- UDP的数据长度也可以这样计算,为什么还要设置一个包长度?
为了处理方便,首部长度要是4的整数倍,加入包长度是为了补全UDP首部长度 4 整数倍
四次挥手
TCP如何保证可靠传输
校验和:校验和需要一致,才能传输成功
发送方:在发送数据之前计算检验和,并进行校验和的填充。
接收方:收到数据后,对数据以同样的方式进行计算,求出校验和,与发送方的进行比对确认应答、序列号:进行传输时,会进行确认应答和数据编号
确认应答:每次收到数据,都要向发送方进行确认应答–>发送ACK报文,ACK中包含一个确认号ack,ack告诉发送方:已收到了哪些数据,下一次从哪开始发送序列号: 对每个字节的 数据进行编号,就是序列号
超时重传:超过指定的时间没有收到对方的ACK确认报文,会重新发送
没有收到ACK可能的原因:
①网络原因 全体丢包 ②接收端已经收到了数据,但是ACK报文由于网络原因丢失了超时的最大时间是动态计算的,累计到一定重传次数,任务网络异常,强制关闭连接
三次握手、四次挥手
流量控制(滑动窗口):根据接收端的能力进行发送数据包
拥塞控制:先发送小数据去探路,防止拥塞
TCP报文头部格式
看握手挥手前,先了解TCP报文的头部格式
- 序列号:建立连接时初始化的随机值,每发一次,累加一次
数据字节数。解决乱序问题 。 - 确认号ack:下一次
期望收到的序列号,确认该序号之前的数据已经被接收。解决丢包问题。 - ACK:为1表示有效,为0忽略该字段
- RST:为1表示出现异常,重置连接
- SYN:为1表示发起新连接
- FIN:释放连接
关于ack与ACK
- ack:下一次期望收到的序列号,也就是
seq + 1 - ACK:确认连接
三次握手
三次握手的目的就是要确认两台设备之间是否具有接收和发送数据的能力,不能只是单方面接收or发送
如何来保证双方都能收发数据呢?

- 第一次握手:验证客户端发送能力和服务端接收能力
客户端向服务端发起建立连接的请求,随机生成一个序列号x作为seq,将SYN置为1(表示发起连接),将报文发给服务端 - 第二次握手:验证服务端的发送能力
服务端收到报文,发现SYN=1,知道了客户端想要建立连接,将客户端发过来的序列号x保存,随机生成一个发往客户端的序列号y作为seq,将SYN置为1,ACK置为1,ack=x+1,将报文发送给客户端 - 第三次握手:验证客户端的接收能力
客户端收到ACK=1,ack=x+1,知道了服务端收到了完整的报文
发现SYN=1,知道了服务端同意建立本次连接
将服务端收到的seq=y保存,发送ACK=1,ack=y+1,seq=x+1
seq=x+1,是因为,第一次握手发送ACK报文占据一个序列号,本次从+1开始
服务端收到报文后发现ACK=1,ack=x+1:知道客户端收到了服务端的确认,本次连接建立
不携带数据的ACK报文不占据序列号,也就是第三次握手的ACK不占用seq
建立连接后,第一次正式发送数据时,seq还是第一次握手时的seq+1
四次挥手

假设客户端发送的seq=x,服务端发送的seq=y。
TCP建立连接后客户端总共发送了m个字节的数据
服务端在客户端发FIN报文前总共回复了n个字节的数据
- 第一次挥手:
客户端请求释放连接,发送FIN报文,FIN=1,seq=u
这里的u=x+m+1,也就是第一次握手时的序列号+1+客户端发送的数据量
1是建立连接时占据的一个序列号 - 第二次挥手
服务端收到FIN后,向客户端发送确认报文,ACK=1,seq=v,ack=u+1
v=y+n,这时服务端处于关闭等待状态,需要等数据发送完后,再向客户端发送FIN报文 - 第三次挥手
服务端发送完数据后,向客户端发出FIN报文,FIN=1,ACK=1,seq=w,ack=u+1
w = y+n+最后发送的数据量 - 第四次挥手
客户端收到FIN报文后,向服务端发送确认报文,ACK=1,seq=u+1,ack=w+1
客户端确认报文发出后,不是马上释放连接,要经过2MSL(也就是2倍的最长报文段寿命)后再释放连接,服务端收到ACK确认后,会立刻释放连接
注意:
①客户端发出FIN报文段后不能再发送数据,可以接收数据
②FIN报文段不携带数据也要占据一个序列号
③服务端释放连接比客户端要早
为什么TCP连接设计为3次?
1. 阻止过期连接的建立
2. 同步通信双方的初始序列号
3. 避免资源浪费
1.阻止历史重复连接初始化
客户端发起多次连接请求,因为网络原因,旧的SYN报文比新的SYN报文先送达服务端,只有两次握手的话,服务端无法判断这是过期的连接还是新的连接,因此需要第三次握手,客户端根据发来的报文和自身的上下文判断,如果是过期连接,就发送RST报文给服务端,中止本次连接
2.同步双方的初始序列号
TCP是可靠的通信协议,通信双方需要维护一个序列号
- 接收方可以去除重复的数据
- 接受方可以根据序列号按顺序接收
- 可以标记哪些是已经发送的,哪些是被对方接收的
如果只有两次握手,只能保证客户端的发送能力和服务端的接受能力
无法验证客户端是否接收到,服务端是否发送出去
3.避免资源浪费
如果是两次握手,当客户端的SYN报文在网络中阻塞,客户端没有收到ACK确认报文,就会重新发送SYN报文,两次握手服务端无法知道客户端是否收到了自己的确认连接ACK,每次收到SYN都会建立一个连接,这样在服务器中生成多个冗余的无效连接,造成了资源的浪费,所以三次握手是保证建立可靠连接的最小次数。
半连接队列与全连接队列
- syns queue :半连接队列。保存SYN-SENT、SYN-RCVD状态的连接
- accept queue :全连接队列。保存established状态,还没有被accept()调用的连接

第一次握手:服务端收到SYN,将未建立的连接放入半连接队列
第二次握手:服务端发送SYN,ACK
第三次握手:服务端收到客户端的ACK,如果全连接队列没有满,就将半连接队列中的连接放入全连接队列,如果已经满了,就拒绝本次连接
什么是SYN洪泛攻击?如何防御SYN攻击?
SYN攻击:短时间内伪造大量不存在的IP地址,向服务端发送SYN报文,服务端每次接收到一个SYN,就会放入半连接队列中,由于IP不存在,服务端发送出去SYN+ACK报文,无法获取来自客户端的ACK响应,大量的连接处于SYN-RCVD状态,半连接队列满后,就会无法处理正常的连接请求。
防御SYN攻击:
- 缩短超时时间
- 增加最大半连接队列的大小
- SYN cookie 技术
服务端收到SYN报文返回一个SYN+ACK时,根据SYN报文计算出一个cookie值,收到客户端的ACK报文时,不直接分配数据区,而是根据cookie值检查该ACK包的合法性,如果验证是合法的,再分配专门的数据区进行将来的连接
linux中查看SYN相关配置:sysctl -a | grep syn
三次握手中为什么只有第三次可以携带数据?
前两次握手都发送SYN报文
第一次握手携带数据容易被攻击,攻击者在SYN中放如大量数据,重复发送SYN报文,服务端要耗费大龄资源去接收
第三次握手,客户端处于established状态,知道啦服务端的收发能力是正常的,可以携带数据发送
为什么关闭连接要挥手4次?
服务端和客户端都没有数据发送时,才可以关闭TCP的连接。
客户端发送FIN报文,表示客户端已经没有数据要向服务端发了,但是客户端不知道服务端还有没有数据向自己发送,服务端收到客户端的FIN报文后,回复ACK确认报文,表示自己收到了释放连接请求,但是自己还有数据没有发完,等数据发完后再发送FIN报文给客户端,表示自己同意释放本次连接,最后客户端再给服务端一个ACK确认报文。
TIME_WAIT和CLOSE_WAIT的区别?
- TIME_WAIT 出现在主动断开连接的一方,等待2MSL后才关闭连接
- CLOSE_WAIT 出现在被动断开连接的一方,直接关闭连接
TIME_WAIT:解决对方没有收到第四次挥手的报文的情况。第四次挥手后,如果对方没有收到报文,就会重新发送第三次报文,等待响应,2MSL之后关闭连接
CLOSE_WAIT:收到FIN报文后,发送ACK确认,还有数据要发送就会进入CLOSE_WAIT状态
为什么第四次挥手后,客户单要等2MSL的时间才释放TCP连接?
MSL(Maximum Segment Lifetime)最大报文生存时间。一次握手、挥手、收发数据的最大时间就是MSL
如果第四次挥手的报文丢失,服务端没有收到确认报文,就会重新发送第三次握手的FIN报文,等待客户端确认,一来一回的最长时间就是2倍的MSL,所以需要等待2MSL后来确认服务端收到了确认报文
如果已经建立了连接,客户端突然故障了怎么办?
TCP中有一个保活机制
定义一个保活的时间段,在时间段内,服务端没有收到数据,就会,每隔一段时间发送一个探测报文,连发几次探测后没有收到客户端的响应,服务端就知道了客户端发生故障,关闭本次连接
网络层 详解
IP
给主机分配的逻辑地址,可以是动态的
通过IP地址的⽹络位可以确定某个主机所在⽹络的位置,从⽽明确⼀条数据转发的路径。通过路由器不断寻址找到⽬的⽹段。
有了IP地址,为什么还要MAC地址
在局域⽹中通信需要通过MAC地址表记录主机和接⼝的映射关系来进⾏通信。
虽然同⼀⽹段也会⽤到ip地址,但是它在局域⽹中不起作⽤,因为arp是⽤于⽹络中寻址的,⽽在局域⽹中我们不需要⽤到⽹关进⾏通信,只需要找到⽬的MAC即可。
ARP
地址解析协议,是根据IP地址获取MAC地址的一个网络层协议
每台主机都会在自己的ARP缓冲区维护一个ARP列表,存储IP地址和MAC地址的对应关系
局域网中,数据传输需要的是MAC地址,不是IP
ARP只在同一个广播域生效
ARP 工作过程
源主机向目标主机发送请求数据包时,先检查本机ARP缓存中有没有该IP对应的MAC地址,有就直接向该MAC地址发送数据包,没有就发起包含目标主机的IP地址的ARP请求,ARP请求会广播到局域网中所有主机。
收到请求的主机会取出数据包中的IP来和自己的IP比较,如果相同就返回自己的MAC地址,不同就说明不是找自己的,丢弃数据包。
源主机收到返回消息,将返回的MAC地址与IP存到本机ARP缓存中保留一段时间,下次请求时,直接查询缓存,节省资源
ARP攻击
ARP协议是建立在网络中各个主机互相信任的基础上的,局域网络上的主机可以自主发送ARP应答消息,其他主机收到应答报文时不会检测该报文的真实性就会将其记入本机ARP缓存;
由此攻击者就可以向某一主机发送假的ARP应答报文,使其发送的信息无法到达预期的主机或到达错误的主机,这就构成了一个ARP欺骗。