为什么要三次握手四次挥手

244 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第16天,点击查看活动详情

为什么要三次握手

第一点:三次握手是为了保证客户端和server端的接收和发送功能正常,保证可靠的数据发送与接收

如果只有一次握手,只能确保server接收正常,客户端发送正常

两次握手只能保证客户端接收发送正常,server端接收正常,不能保证server端发送正常

只有三次握手能保证server端和客户端接收和发送都正常

第二点:是为了避免历史连接,因为客户端连续发送多次syn建立连接的报文的时候,会出现网络拥堵的情况,旧的syn报文会比新的syn报文先到服务端,此时服务端返回一个syn+ack报文给客户端,客户端收到后根据自身的上下文判断这是一个历史连接,发送rst给服务端中断连接。如果是两次握手的话,就不能判断当前连接是否是历史连接,三次握手则可以在客户端准备发送第三次报文的时候判断当前连接是否是历史连接,如果是历史连接就发送rst报文,如果不是就发送ack报文。

第三点:三次握手能同步双方初始序列号。可见,序列号在 TCP 连接中占据着非常重要的作用,所以当客户端发送携带「初始序列号」的 SYN 报文的时候,需要服务端回一个 ACK 应答报文,表示客户端的 SYN 报文已被服务端成功接收,那当服务端发送「初始序列号」给客户端的时候,依然也要得到客户端的应答回应,这样一来一回,才能确保双方的初始序列号能被可靠的同步。

四次握手其实也能够可靠的同步双方的初始化序号,但由于第二步和第三步可以优化成一步,所以就成了「三次握手」。

而两次握手只保证了一方的初始序列号能被对方成功接收,没办法保证双方的初始序列号都能被确认接收。

第四点:能避免资源的浪费,因为两次握手的话,当客户端拿到syn请求连接在网络中阻塞,客户端没有收到ack报文,就会重新发送syn,如果没有第三次握手,服务器不清楚客户端是否收到自己发送的连接的ACK确认信号,所以每次收到一个syn就主动简历一个连接,如果客户端的syn阻塞,重复发送多次syn报文,那么服务器在收到请求后就会建立多个冗余的无效链接,造成不必要的资源浪费。即两次握手会造成消息滞留情况下,服务器重复接受无用的连接请求 SYN 报文,而造成重复分配资源。

为什么要四次挥手

关闭连接的时候,客户端向服务端发送fin,仅仅表示客户端不在发送数据但是还能接收数据

服务器收到fin报文,先回一个ack,而服务端可能还有数据需要处理和发送, 等到服务端不在发送数据了,才发送一个fin报文表示客户端现在可以关闭了

从上面的过程我们可以发现服务端通常需要等待数据完成发送和处理,所以一般服务端的ack和fin分开发送,所以导致比三次握手多一次。

如果是两次挥手,客户机请求关闭服务端直接关闭了,有可能服务端的数据并没有传输完成,造成数据丢失。如果是三次挥手,服务端数据传输完成立即关闭连接。可能会导致本次tcp连接产生的报文残留在网络中。所以需要四次挥手。