一、三次握手的作用
为了确认双方具有接收和发送的能力。
二、三次握手的原因
1. 可以阻止重复历史连接的初始化(主要原因)。
2. 可以同步双方的初始序列号。
3. 可以避免资源的浪费。
三、分析原因
1. 为了防止旧的重复连接初始化造成混乱。
当客户端发送了一个 SYN 报文后,突然宕机了,并且这个 SYN 报文还被网络阻塞了,这时服务端还没有接收到客户端发过来的报文,之后,当客户端重启后,又重新向服务端建立连接,再次发送 SYN 报文(注意这次发送的 SYN 报文与之前发送的 SYN 报文的序列号是不同的,属于两个不同的报文)。
对于两个 SYN 报文,服务端是先接收 [旧 SYN 报文],再接收 [新 SYN 报文],那么当 [旧 SYN 报文] 先到达服务端后,服务端就会返回一个 SYN+ACK 报文给客户端。
三次握手时,客户端收到后可以根据自身的上下文,判断是否是一个历史连接(序列号过期或超时),那么客户端就会发送 RST 报文给服务端,表示终止这一次连接。如果是两次握手,就无法阻止历史连接,因为客户端没有中间状态 RST 给服务端来阻止连接,导致会建立一个历史连接,造成资源浪费。
2. 同步双方初始序列号
TCP 协议通信的双方,都必须维护一个序列号,序列号是可靠传输的一个关键因素,作用是:
- 接收方可以去除重复的数据;
- 接收方可以根据数据包的序列号按序接收;
- 可以标识发送出去的数据包中,哪些是已经被对方收到的;
客户端发送携带 [初始序列号] SYN 报文给服务端后,服务端也需要回一个 ACK 应答报文,标识客户端发送的报文已被成功接收,当服务端发送 [初始序列号] 给客户端时,依然也需要客户端的应答回应,这样一来一回,才能确保双方的初始序列号能被可靠的同步。
四次握手也能够可靠的同步双方的初始化序号,但可以进行优化一下,就成了三次握手了。
3. 避免资源的浪费
如果只有两次握手,当客户端的 SYN 请求连接在网络中阻塞,客户端没有接收到 ACK 报文,就会重新发送 SYN,由于没有第三次握手,服务器不清楚客户端是否接收到了自己发送的建立连接的 ACK 确认信号,所以服务器每收到一个 SYN 就只能先主动建立一个连接,就会建立多个冗余的无效链接,造成不必要的资源浪费。所以,两次握手不具备可靠性。