三次握手过程
恋爱模拟例子
以谈恋爱为例,两个人能够在一起最重要的事情是首先确认各自爱和被爱的能力。接下来我们以此来模拟三次握手的过程。
第一次:
男: 我爱你。
女方收到。
由此证明男方拥有爱的能力。
第二次:
女: 我收到了你的爱,我也爱你。
男方收到。
OK,现在的情况说明,女方拥有爱和被爱的能力。
第三次:
男: 我收到了你的爱。
女方收到。
现在能够保证男方具备被爱的能力。
由此完整地确认了双方爱和被爱的能力,两人开始一段甜蜜的爱情。(真不错啊~)
真实握手
其实三次握手与上面的例子非常相识,目的就是确认客户端与服务器的发送和接受能力。
三次握手的过程:
最开始双方都处于 CLOSED 状态。然后服务端开始监听某个端口,进入了LISTEN 状态。
第一次:客户端主动发起连接,发送 SYN , 变成了 SYN-SENT 状态。
第二次:服务端接收到,并返回SYN和ACK来响应客户端发来的SYN,自己变成了 SYN-REVD。
第三次:客户端再发送ACK给服务端,自己变成了 ESTABLISHED 状态;服务端收到 ACK之后,也变成了ESTABLISHED 状态。
为什么是三次?
- 为什么不是两次?
三次握手的目的是为了确认客户端与服务端的发送和接受能力,而两次无法确认客户端的接受能力。 - 为什么不是四次?
可以是四次,但没必要。
三次握手可以携带数据吗?
第三次握手的时候,可以携带。前两次握手不能携带数据。
如果前两次握手能够携带数据,那么一旦有人想攻击服务器,那么他只需要在第一次握手中的 SYN 报文 中放大量数据,那么服务器势必会消耗更多的时间和内存空间去处理这些数据,增大了服务器被攻击的风险。
第三次握手的时候,客户端已经处于 ESTABLISHED 状态,并且已经能够确认服务器的接收、发送能力正常,这个时候相对安全了,可以携带数据。
四次挥手
过程:
刚开始双方处于 ESTABLISHED 状态。
第一次:客户端要断开了,像服务端发送FIN报文,客户端变成FIN-WAIT-1状态。
第二次:服务端接受后向客户端发送ACK报文,变成CLOSEED-WAIT状态,客户端接受到了服务器的确认,变成FIN-WAIT2状态
第三次:服务端向客户端发送FIN+ACK报文,进入LAST-ACK状态
第四次:客户端收到服务器发来的FIN+ACK后,自己变成了TIME-WAIT状态,然后发送ACK给服务端。
此时,客户端需要等待2个MSL(报文最大生存时间),在这段时间内如果客户端没有收到服务端的重发请求,那么表示ACK成功到达,挥手结束,否则客户端重发ACK。
等待2MSL的意义(为什么)
- 不等待会怎样?
客户端发送的ACK报文段可能会丢失,若客户端不等待2MSL时间,则无法收到服务器重传的FIN+ACK报文段,所以就不会重传ACK报文,则服务端将无法进入CLOSED状态。 - 意义
1、保证客户端发送的最后一个ACK报文段能够到达服务器。这个ACK报文段有可能会丢失,使得处于WAIT-ACK状态的服务端接收不到对已发送的FIN+ACK的确认,服务端超时重传FIN+ACK报文,而客户端能在2MSL时间内收到这个重传的FIN+ACK报文,从而重新发送ACK报文,重新启动2MSL计时器,最后客户端和服务端都进入CLOSED状态。
2、防止‘已失效的链接报文段’出现在本链接中。若客户端直接跑路,当服务端还有很多数据包要给客户端发,且还在路上的时候,此时客户端的端口此时刚好被新的应用占用,那么就接收到了无用数据包,造成数据包混乱。所以,最保险的做法是等服务器发来的数据包都死翘翘再启动新的应用。
为什么是四次挥手而不是三次?
- 原因
关闭连接时,当服务器收到客户端发送的FIN报文时,很可能并不会立即关闭SOCKET,所以先回复一个ACK报文。只有等到服务器所有的报文都发送完了,才能发送FIN报文,因此不能一起发送。故需要四次挥手。 - 为什么不是三次握手
如果为三次握手,则客户端发送FIN报文后,服务端长时间的延迟可能会导致客户端误以为服务端没有收到FIN报文,从而不断重新发送FIN。
半连接队列和SYN FLood攻击的关系
三次握手前,服务端的状态从CLOSED变成LISTEN,同时在内部创建两个队列:半连接和全连接
半连接队列
当客户端发送SYN到服务端,服务端收到后回复ACK和SYN,状态由LISTEN变成SYN_RCVD,此时这个链接就被推入半链接队列。
全连接队列
当客户端返回ACK,服务端接受后,三次握手完成。这个时候连接被推入另一个TCP维护的队列,也就是全连接队列。
SYN Flood 攻击原理
SYN Flood 属于典型的 DoS/DDoS 攻击。其攻击的原理很简单,就是用客户端在短时间内伪造大量不存在的 IP 地址,并向服务端疯狂发送 SYN 。对于服务端而言,会产生两个危险的后果:
1)处理大量的 SYN 包并返回对应 ACK , 势必有大量连接处于 SYN_RCVD 状态,从而占满整个半连接队列,无法处理正常的请求。
2)由于是不存在的 IP,服务端长时间收不到客户端的 ACK ,会导致服务端不断重发数据,直到耗尽服务端的资源。
总结
本文仅为自己准备面试时对三次握手与四次挥手的一些理解。