三次握手】
1、当客户端向服务器发起第一次请求(SYN)时,其自身就会处于一种SYN_SEND的状态(即等待发送)
2、处于listen状态的服务器接收到客户端发起的请求之后,会进入SYN_RCVD状态(即等待接收)
3、服务器向客户端发出SYN+ACK,服务器收到之后,有原来的SYN_SEND状态变为ESTABLISED(连接)状态。
4、当服务器收到这个ACK之后,便同样会进入到ESTABLISED状态
5、链接本身是有成本的:耗费空间+时间,而TCP是面向连接的,即三次握手成功之后,需要client和server共同维护
6、注意到,我们这里的ACK和SYN有一次压缩起来了,所以如果硬要说的话,是四次握手,但是其默认都是压缩起来了,所以我们就按照三次握手来说。
那为啥是要有三次握手?一次、两次、四次不行?
首先一次肯定是不行的,为什么呢?如果发出去一个SYN就算建立连接了,那这和udp有什么区别呢,即便服务器没有拿到这个SYN请求,我的客户端已经认为建立连接了?况且服务器连接的维护是需要成本的。如果一次就建立连接的话,如果一个恶意软件在短时间内对我进行大量的SYN,那我的服务器不就崩掉了?
那两次呢?
如果是这样的话,那服务器发回去一个ACK之后,它就直接认为自己建立连接了。这本质上和一次握手并没有什么差别。
一次和两次握手极容易收到SYN洪水攻击:无条件的发SYN就建立连接的话,那我大量的发SYN,服务器就直接挂掉了。
那为什么要三次呢?
我们说TCP是全双工的,所以,双方在通信之前,需要讲信道的状况验证一下是否通畅。即客户端和服务器都至少有一次收、有一次发。 故:用最小的成本验证全双工。
如果是四次握手的话,那前三次的报文丢失我们不怕,但是第四次的报文我们还是害怕丢失的,多这个一次就没有意义了。更多的也是一样的道理。(并且不要让服务器出现连接建立误判的清空,从而减少服务器的资源浪费)
这个时候,在面对SYN洪水的时候,就类似杀敌一千自损八百的情形,即要想让服务器挂连接,那么自己也要挂相应数量的连接。