我们都知道TCP协议是面向连接的, 建立连接时需要三次握手, 断开连接时需要四次挥手, 那三次握手和四次挥手的具体流程是怎样的呢? 为什么建立连接时需要三次握手, 两次行不行? 为什么断开连接时需要四次挥手, 三次行不行? 下面我们就一起来了解下.
TCP协议格式
我们先来了解下TCP报文中一些重要的字段.
- 源端口和目的端口
客户端和服务端的端口号. - ***
***是报文段发送的数据中第一个字节的***, 比如***为100, 数据有300个字节, 那下一个报文段的***为400. ***确保了TCP传输的有序性. - 确认号
指下一个期待收到的字节***, 表明该***之前的所有数据已经正确无误的收到. 确认号只有当ACK标识位为1时才有效, 比如TCP连接第二次握手时ACK标识位为1. - 标识位
- SYN
同步***, 用于建立连接过程. 在连接请求中SYN=1和ACK=0表示没有确认号. SYN=1和ACK=1表示有确认号. - ACK
同步确认号, 为1表示确认号有效, 为0表示确认号无效. - FIN
释放连接, 为1表示发送方已经没有数据发送了.
- SYN
- 窗口
滑动窗口大小(TCP缓冲区大小), 用来控制发送端发送数据的速率, 从而达到流量控制. - 数据
TCP 报文段中的数据部分是可选的.
TCP协议的三次握手
三次握手的目的就是为了确认双方的接收能力和发送能力是否正常, 指定自己的初始***为后面的可靠性传送做准备, 交换TCP窗口大小信息.
- 第一次握手:客户端向服务端发送一个连接报文(标识位SYN=1, ***为一个随机值).
- 第二次握手:服务端收到客户端的连接报文后, 返回一个确认报文(标识位SYN=1和ACK=1, ***为一个随机值, 确认号为客户端的*** + 1).
- 第三次握手:客户端收到服务端的确认报文后, 再向服务端发送一个确认报文(标识位ACK=1, ***值等于上一次收到的确认号, 确认号为上一次收到的*** + 1).
三次握手完毕后, 客户端与服务端建立连接, 然后就可以开始数据传输. 前面两次握手不能传输数据, 第三次握手可以传输数据, 这是为了避免恶意攻击.
TCP协议的四次挥手
- 第一次挥手:客户端完成它的数据发送任务后, 向服务端发送一个终止报文, 表示自己不再发送数据. (标识位FIN=1, ***值等于上一次收到的确认号)
- 第二次挥手:服务端收到客户端的终止报文后, 会向客户端返回一个确认报文.(标识位ACK=1, ***值等于上一次收到的确认号, 确认号为客户端的*** + 1)
- 第三次挥手:服务端完成它的数据发送任务后, 会向客户端发送一个终止报文, 表示自己不再发送数据.(标识位FIN=1, ***值等于上一次收到的确认号, 确认号为第二次挥手的确认号 + 1)
- 第四次挥手:客户端收到服务端的终止报文后, 会向服务端发送一个确认报文. (标识位ACK=1, ***值等于上一次收到的确认号, 确认号为上一次收到的***+1)
在第二次挥手后, 服务端会继续传输数据报文给客户端, 客户端收到数据报文后会返回一个确认报文.
为什么TCP协议建立连接需要三次握手?
这个问题其实是为什么建立连接时需要第三次握手? 因为如果只有两次握手, 服务端接收到客户端建立连接的请求后, 就建立一个新的连接, 那么在网络延迟的情况下, 客户端可能会发送多个建立连接的请求, 最终在客户端与服务端之间就会建立了多个TCP连接, 耗费资源. 而加上第三次握手后, 如果客户端与服务端之间已建立连接, 客户端就不会再发送确认报文了.
为什么TCP协议断开连接需要四次挥手?
因为TCP协议是一个双向通信的协议, 客户端完成它的数据发送任务后, 请求断开连接, 这只是代表客户端不再发送数据了, 客户端还需要接收服务端发送过来的数据, 只有等服务端也完成它的数据发送任务后, 才能断开连接.