1. TCP / IP五层模型和OSI七层模型
1)OSI七层模型
OSI七层网络模型是一个逻辑上的定义和规范:把网络从逻辑上分为7层
应用层: 为应用程序提供交互服务
表示层: 将数据格式转换成网络标准数据格式
会话层: 管理通信,负责建立和断开通信连接
传输层: 向主机进程提供通用的数据传输服务
网络层: 选择适合的路由和交换节点,确保数据的传送
数据链路层: 将网络层传下来的IP数据包组装成数据帧,在相邻节点之间传送
物理层: 实现相邻节点之间比特流的透明传输
2)TCP/IP 五层模型
在 TCP/IP 五层模型中,每层都呼叫它的下一层所提供的服务来完成自己的需求
应用层: 为应用程序提供交互服务,如电子邮件传输(SMTP)、文件传输(FTP)
传输层: 向主机进程提供通用的数据传输服务,该层主要有以下两种协议:
TCP:提供面向连接的、可靠的数据传输服务
UDP:提供面向无连接的、尽最大努力的数据传输服务,但不保证数据传输的可靠性
网络层: 选择适合的路由和交换节点,确保数据及时传送。主要包括IP协议
数据链路层: 将网络层传下来的IP数据包组装成数据帧,在相邻节点的链路上传送
物理层: 负责光/电信号的传播,在相邻节点之间比特流的透明传输
2. TCP和UDP
1) TCP首部结构
2)UDP首部结构
3)TCP和UDP的区别
2.2 UDP和TCP对应的应用场景
TCP应用场景: TCP面向连接,能够保证数据的可靠性传输,因此常用于:
- FTP 文件传输
- HTTP服务器
UDP应用场景: UDP面向无连接,他可以随时发送数据,传输速度快,因此常用于:
- 视频、音频等多媒体通信
- 广播通信
3. TCP 建立连接时的三次握手
简单流程如下:
第一次握手:客户端向服务端发送 同步报文(SYN),同时选择一个 随机数 x 作为初始序号,随后进入 同步已发送状态(SYN_SENT),等待服务端确认
第二次握手:服务端在收到客户端发来的同步报文之后,服务端向客户端发送 同步确认报文(SYN + ACK),同时选择一个 随机数 y 作为初始序号,确认序号为 x + 1,随后服务端由 收听状态(LISTEN)变为 同步已收到状态(SYN_RECV)
第三次握手:客户端在接收到服务端发来的同步确认报文之后,客户端向服务端发送 同步确认报文(SYN + ACk),序号为 x + 1,确认序号为 y + 1,随后客户端进入 连接已建立状态(ESTABLISHED),服务端在接收到这个同步确认报文之后,也立即进入 连接已建立状态(ESTABLISHED)
1)为什么需要三次握手,而不是两次
三次握手才能让双方都确认自己和双方的接受能力都正常
第一次握手:客户端发送同步报文,服务器接收同步报文,服务器可以确定自己的接收能力正常和对方的发送能力正常
第二次握手:服务端发送同步确认报文,客户端接收同步确认报文,客户端可以确认自己的接收能力正常和发送能力正常,以及对方的接收能力正常和发送能力正常
第三次握手:客户端发送同步确认报文,服务端接收同步确认报文,服务端可以确认自己的发送能力正常,以及对方的接收能力正常
告知对方自己的初始序列号,并且确认收到对方的初始序列号
TCP 实现可靠传输的原因之一就是维护序列号和确认序列号,实现确认应答机制,通过这两个字段可以让双方知道哪些数据已经发出,哪些数据被对方确认对方接收,如果只是两次握手,那么双方只能知道对方的序列号,而不知道确认序列号
2)为什么是三次握手,而不是四次握手
因为三次握手之后就已经可以确认双方的发送和接受能力正常,而且双方也都知道对方的序列号和确认序列号,就不需要第四次了
3)如果第三次握手的 ACK 报文丢失,会发生什么
第三次握手的 ACK 报文丢失,服务端会根据超时重传机制,重新向客户端发送 SYN + ACK 报文,以便客户端重新发送 ACK 报文
如果重发指定次数之后,服务端还未收到客户端的 ACK 报文,那么一段时间之后,服务端就会自动断开这个连接
4. TCP 建立连接时的四次挥手
大致流程如下:
第一次挥手:主动断开方向被动断开方发送 释放报文(FIN),同时 随机选取一个数作为序号,随后主动连接方变为 结束等待1状态(FIN_WAIT_1)
第二次挥手:被动断开方向主动断开方发送 确认报文(ACK),同时随机选取一个数作为序号,并且将主动断开方发来的序号 +1 作为确认序号,随后被动连接方变为 关闭等待状态(CLOSE_WAIT),主动断开方在收到确认报文之后变为 结束等待2状态(FIN_WAIT_2)
第三次挥手:被动断开方向主动断开方发送 释放报文(FIN),同时将上一次发送数据的序号 +1作为本次序号,随后被动断开方变为 最后确认状态(LAST_ACK)
第四次挥手:主动断开方向被动断开方发送 确认报文(ACK),同时将上次发送数据的序号 +1作为本次序号,并且将被动断开方发送来的序号 +1 作为确认序号,随后主动断开方变为 等待时间状态(TIME_WAIT),被动断开方在收到确认报文之后变为 连接关闭状态(CLOSE)。主动连接方在经过 2MSL 时间 之后变为 连接关闭状态(CLOSE)
1)为什么需要四次挥手
被动断开方在收到主动断开方的 FIN 报文之后,可能还会有一些数据需要发送,所以不会立即断开连接,但是会做出应答,返回给主动断开方 ACK 报文
在数据发送完之后,被动断开方会向主动断开方发送 FIN 报文,请求断开连接,主动断开方收到之后返回一个 ACK 报文,连接才会断开。被动断开方的 FIN 报文和 ACK 报文一般分开发送,从而导致多了一次,所以需要四次挥手
2)为什么主动断开方的 TIME_WAIT 状态必须等待 2MSL
主要原因有:
为了确保被动关闭方能够收到最后一次 ACK 报文,正常关闭连接
第四次挥手时,主动关闭方发送的 ACK 报文不一定会到达被关闭方,如果被动关闭方长时间未收到,就会重传 FIN 报文,并等到新的 ACK 报文,所以主动关闭方在 TIME_WAIT 等待 2MSL时间后,就可以保证双方的连接正常关闭
防止上一次 TCP 连接的数据包影响到下一次连接
如果主动断开方不等待 2MSL 时间直接关闭连接,然后又与另一个主机建立连接,并且上一次的被动关闭方未收到 ACK 报文,重传 FIN 报文,那么新的 TCP 连接就会收到一些不希望收到的数据。因此,需要等到 2MSL 时间,确保网络中的报文全部消失再关闭连接
5. TCP 如何保证可靠性
TCP提供了检验和、序列号/确认应答、超时重传、滑动窗口、拥塞控制和流量控制等方法实现可靠性传输
1)检验和
通过检验和的方式,接收端可以检测出来数据是否出现差错,假如出现差错就会丢弃TCP段,重新发送
2)序列号/确认应答:
TCP传输过程中,接收方每次收到数据后,都会给发送方进行确认应答,即发送ACK报文,这个ACK报文中包括对应的确认序列号、本次接收到哪些信息、下一次数据从哪里发送
序列号不仅仅是应答的作用,有了序列号就能够将接收到的数据根据序列号排序,并且去除相同序列号的数据
3)滑动窗口:
滑动窗口提高了报文传输的效率,避免发送方一次性发送数据过多导致接收方无法正常处理
4)拥塞控制:
数据传输过程中,可能由于网络状态的问题,造成网络拥堵,加入拥塞控制就可以在保证可靠性的同时,提高性能
5)流量控制:
如果主机A一直向主机B发送数据,不考虑主机B的接受能力,则可能导致主机B的接收缓冲区满了而无法接收数据,从而导致丢失大量数据,引发重传机制。而在重传过程中,如果主机B的缓冲区仍未好转,将会浪费大量时间进行重传,降低传输效率。所以引入流量控制机制,主机B通过告诉主机A自己缓冲区的大小,来控制发送的数据量。
6. 滑动窗口
在进行数据传输时,如果传输的数据比较大,就需要拆分为多个数据包进行发送。TCP 协议需要对数据进行确认后,才能发送下一个数据包。这样一来,就会在等待确认应答环节浪费时间。
为了避免这种情况,TCP 引入了窗口的概念。窗口大小指的是不需要确认应答也可以发送的数据的最大值
可以看到滑动窗口起到了一个限流的作用,滑动窗口的大小决定了 TCP 发送数据包的速率,而滑动窗口的大小取决于拥塞控制窗口和流量控制窗口二者间的最小值
7. 拥塞控制
TCP 的拥塞控制是一种在网络发生拥塞时,发送方会维持一个叫做拥塞窗口的变量来适当减少数据发送速率的机制,以避免数据丢失和网络拥塞恶化
TCP 一共使用了四种算法来实现拥塞控制:
慢开始
拥塞避免
快速重传
快速恢复
1)慢开始
TCP 在建立连接之后,初始的拥塞窗口大小为1,在经过几个传输轮次之后,拥塞窗口开始呈指数增长,直到达到慢开始阈值或者丢包
2)拥塞避免
当拥塞窗口大小达到慢开始阈值或者发生丢包了,就进入拥塞避免阶段,此时没经过一个传输轮次,拥塞窗口大小就加1,呈线性增长,直到再次发生丢包
在慢开始和拥塞避免阶段,主要出现网络阻塞,就将慢开始阈值变为当前拥塞窗口的一半,再将拥塞窗口大小设置为1
4)快重传
当发送方连续收到三个对同一个报文的确认,就认为该报文段的下一个报文段已经丢失,立即重传
5)快恢复
发送方执行快重传之后,将慢开始阈值设置为当前拥塞窗口大小的一半,然后将拥塞窗口大小设置为慢开始阈值加3(由于收到三个重复确认而增加的),随后进入拥塞避免阶段