网络分层

OSI 七层模型

image-20220826193433007

七层模型的结构清晰,每一层该干什么事。降低复杂性,统一标准,模块化。

  1. 物理层:很重要的一层,最底层,就像一个地基。保证双向传输,双向通讯。
  2. 数据链路层:①提供 MAC 地址;②负责数据帧的转发;③提供错误检查机制(交换机会对数据进行检测,如果发现有丢失,就会通知发送方重传数据)
  3. 网络层:①提供 IP 地址;②连接不同的媒介类型;③根据路由器运行的不同选择最佳路径;④在选择好的路径上路由数据包
  4. 传输层:传输层提供了端口号的概念。建立端口到端口的通信
  5. 会话层:在用于程序之间建立并维护会话连接
  6. 表示层:负责数据加密。比如对称加密、非对称加密…
  7. 应用层:给用户提供一个接口,用户可以通过用于程序来使用 6 层模型

七层模型虽然结构清晰,但是比较复杂并且不怎么实用,运行效率偏低。于是四层模型出现了

OSI 四层模型

image-20220826214235624

应用层:提供两个终端设备上的应用程序信息交换的服务,定义消息交换的格式,将消息交给传输层传输

传输层:使用 TCP 和 UDP 协议对消息进行传输

网络层:给分组交换网上不同主机提供通信服务

物理层:使用物理手段将电脑等设备连接起来 比如光纤线路

TCP 和 UDP

TCP (传输控制协议) 和 UDP (用户数据报协议 ) 这两个是 TCP/IP 协议的核心,都属于传输层。这一层主要负责网络中主机的定位。其中 TCP 是面向连接,具有可靠的数据传输机制。在发送数据之前必须建立连接。保证数据不会丢失,按顺序抵达 。UDP 则是无连接,不关心数据是否被正确接受到,只管发送,是一种不可靠的协议。这两种协议中,因为 TCP 要保证可靠性,所以只支持一对一通信,而 UDP 可以同时和多个主机进行通信。TCP 也是面向字节流的 而 UDP 是面向报文的

TCP 的三次握手机制

第一次握手:客户端向服务端发送一个请求报文,也就是 seq,这个时候 客户端进入 SYN-SENT 阶段

第二次握手:服务端收到这个报文后,就会将自己的 SYN 设置为 1(SYN 表示当前是否被连接),ACK 也设置为 1。同时生成一个初始序列号,发送给客户端,发送完成后自己进入 SYN-RECEIVED 状态

第三次握手:客户端收到服务端刚刚发送的同意应答后,再向服务端发送一个确认的报文,客户端发送完成后进入 ESTABLISHED 状态,服务端收到这个应答后,并进行检查后,也进入 ESTABLISHED 状态。完成三次握手

是不是看着很复杂?一头雾水?我用几句话来总结一下。

A 主机想向 B 主机通信,A 告诉 B 主机通信请求,让 B 给自己一个序列号(完成一次握手)。B 主机收到这个请求,表示确认 (ACK 设置为 1),然后给 A 一个序列号(二次握手)。A 收到后表示确认,发送表示” 收到” 的报文,开始正式传输数据(三次握手)。

TCP 的四次挥手

第一次挥手:客户端向服务端发送释放连接请求,发送 FIN 报文,客户端状态变为 FIN_WAIT_1。此时客户端仍然可以接收数据

第二次挥手:服务端收到 FIN 报文后,会向客户端发送 ACK 应答报文,但是连接并不会立刻终止,因为可能有未完成的数据。此时服务端的状态为 CLOSE_WAIT (等待关闭),客户端进入 FIN_WAIT_2

(如果这个时候服务端因为某些原因没有给客户端回应,那么客户端会永远处于 FIN_WAIT_2 这个状态)

第三次挥手:当服务端已经把数据全部发送完成,就会给客户端发送一个 FIN 报文,通知客户端连接可以正常关闭。此时服务端进入 LAST_ACK (最终确认) 状态

第四次挥手:客户端收到服务端的 FIN 报文,给服务端发送 ACK 应答报文,服务端收到 ACK 应答报文后,关闭连接。此时客户端状态为 TIME_WAIT,同时等待 2MSL(MSL:报文在传输过程中的最大生命周期。这里等待 2 倍的时间),如果等待期间没有再收到服务端的 FIN 报文,就会关闭连接,进入 CLOSED 状态。完成四次挥手。

为什么第四次挥手时,客户端要等待 2MSL?

主要是确保服务端可以收到客户端发送的 ACK 应答报文,从而进入关闭状态。

试想一种情况,第四次挥手的时候,客户端给服务端发送 ACK 应答报文,发送完直接进入 CLOSED 状态,而不是 TIME_WAIT。如果发送的 ACK 丢失了呢,这样服务端就收不到客户端的 ACK 应答,等待 1MSL 后,重发请求释放也发不过去,因为客户端已经进入 CLOSED 状态了。服务端就会一直处于 LAST_ACK 状态,无法正确释放。而让客户端等待 2 倍的 MSL 时间关闭,就算最后的 ACK 应答报文丢失了,服务端也可以重新发送释放请求并被正常接收。

建立连接只用了三次,为什么关闭连接需要四次?

建立连接的时候,将 ACK 和 SYN 放在了同一个报文内

关闭连接的时候,客户端关闭后,但也要继续接收数据。所以这里分了 2 发送 ACK 报文和 FIN 报文(先返回 ACK 表示进入关闭状态 (此时可以接收),FIN 则完全关闭连接)

UDP 的使用场景

UDP 因为其自身对传输可靠性不高,延迟低,无连接等状态,所以适合实时场景。

  • 网络直播
  • 网络游戏
  • 流媒体
  • 移动通信

UDP 一定比 TCP 快吗?

不一定。UDP 虽然速度快,但是有一个非常头疼的难题,那就是丢包问题。相信肯定会有玩游戏的表示,我一梭子全打上了,他一滴血没掉!对于丢包,谁都不愿意碰到。但如果我们用 UDP 传输一个特别大的数据时,TCP 会根据 MSS 大小进行分段传输,如果发生丢包,重新穿这个分段就可以了。UDP 不会分段,如果发生丢包情况,重新上传整个数据。在这种情况下,UDP 就比 TCP 效率低了

域名中的 A 记录与 CNAME 是什么?

A 记录是域名与 ip 的映射关系。比如我的服务器 ip 是 10.111.201.2,域名是 sample.com,那么就需要在 dns 中配置一条解析记录,将 10.111.201.2 指向 sample.com 域名

CNAME 是别名记录,顾名思义就是将一个域名映射到另一个域名,例如我现在设置了 C.com 到 B.com 的 CNAME,那么我们实际访问 C.com 都会被转发到 B.com 域名上。