正确理解三次握手&四次挥手

上一篇讲HTTP协议的时候提到了TCP连接的建立和释放,事实上这两个过程就分别对应了三次握手和四次挥手,于是我仔细研究了一下这两个过程,写下这篇文章做个总结。

一、TCP报文格式

三次握手就是客户端和服务端总共发送三个包来确认连接的建立,四次握手是客户端和服务端总共发送四个包来确认连接的释放。这个包指的就是TCP报文,我们来看一下它具体格式:
在这里插入图片描述
1、序号:Seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记。
2、确认号:ack序号,占32位,只有当ACK=1时,ack才有效,ack = Seq+1。
3、标志位:分为URG、ACK、PSH、RST、SYN、FIN。这里主要涉及的有:
ACK:若ACK=1,确认序号有效。
SYN:若SYN=1,发起新的连接。
FIN:若FIN=1,释放连接。

二、三次握手

通俗的来讲一下三次握手的过程(假设Alice给Bob打电话,Alice为客户端,Bob为服务端):
1、Alice给Bob打电话相当于客户端试图与服务端建立连接。
2、Bob接到电话,说了一句:“你好,这里是Bob。”,Alice听到就明白了对方正是Bob,这一步相当于服务端接到了客户端的请求,然后发送消息给客户端,客户端接收到消息确认服务端接收到了自己请求连接的消息。
3、Alice回复了Bob:“你好Bob,这里是Alice。”,Bob听到了后就知道对方是Alice,然后双方就开是交谈了。这一步相当于客户端回复服务端的消息,确认受到了服务端的消息,服务端收到了客户端回复的消息,TCP连接建立成功。
我们具体看看三次握手过程:
在这里插入图片描述
(1)第一次握手:Client将SYN置为1,表示请求建立连接,产生一个随机数seq=J,将该数据包发送给Server。Client进入SYN_SENT状态。
(2)第二次握手:Server收到数据包后通过SYN=1知道Client试图建立连接,Server将SYN和ACK都置为1,ack=J+1,产生一个随机数seq=K,将该数据包发送给Client。Server进入SYN_RCVD状态。
(3)第三次握手:Client收到Server发来的数据包,通过SYN=1知道Server试图建立连接,通过ack=J+1知道Server确实收到了自己的消息,确认后将ACK置为1,ack=K+1,将数据包发送给Server。Server收到后确认ack=K+1,知道Client收到了自己的消息,双方进入ESTABLISHED状态,连接建立成功。
SYN攻击
Server在收到Client发送的请求连接的数据包后发送SYN-ACK后,Server端进入SYN_RCVD状态,此状态称为半连接状态。当Server处于SYN_RCVD时,攻击者伪造大量不存在的IP地址,向Server发送SYN包,Server回复确认包,并等待Client确认,因为是不存在的IP地址,因此Server会不断的重发造成超时,这些伪造的SYN包将长期占用未连接队列,造成正常的SYN因队列已满被丢弃,进而造成网络阻塞或瘫痪。SYN攻击是一种典型的DDOS攻击,如果Server有上有大量处于半连接状态且源IP地址是随机的,就可以断定遭到了SYN攻击。

三、四次挥手

再以刚才的那个例子为例,Alice和Bob在通话:
1、Alice觉得话说完了,Alice说:“今天讲话就到这里吧。”(客户端发送消息告诉服务端释放连接)。
2、Bob听到以后,觉得自己还有一点话没说完,接着讲话。(服务端接着在向客户端发送消息)。
3、Bob也觉得自己讲完了,说:“那今天就到这里吧。”(服务端告诉客户端释放连接)。
4、Alice接收到后双方挂了电话。(相当于释放连接)。
下面是四次挥手的流程图:
在这里插入图片描述(1)第一次挥手:Client将Fin=1,表示请求释放连接,生成一个随机数Seq=M,将数据包发送给Server,Client进入FIN_WAIT_1状态。
(2)第二次挥手:Server收到Fin后,将ACK置为1,ack=M+1,这里事实上还生成了一个随机数Seq=D,将该数据包发送给Client,Server进入CLOSE_WAIT状态。
(3)第三次挥手:Server将Fin=1,生成一个随机数seq=N,将该数据包发送给Client,Server进入Last_ASK状态。
(4)第四次挥手:Client收到Fin=1,知道Server要释放连接,进入TIME_WAIT状态,接着将ACK=1,ack=N+1,将该数据包发送给Server,确认收到了消息。Server收到后进入CLOSED状态。2MSL后Client进入CLOSED状态。

为什么要进行三次握手,只进行两次可以吗?

如果将三次握手改成两次的话,可能发生死锁。我们考虑这样一种情况,Client发送请求连接的消息,Server接收到之后将确认收到的消息发送给Client。如果是两次握手的话,这个时候Server已经认为Client接收到了,连接已经建立成功,Server可以开始发送数据分组了。如果Server传输过去的应答包在中途丢失,Client将接收不到应答包,Client将不知道Server是否已经准备好,不知道Server建立了什么样的序列号,甚至怀疑请求连接的包是否发送给了Server,这种情况下Client将认为没有建立连接,将会一直等待Server发送确认消息。而Server发送的数据分组因为被Client忽略,Server会等不到Client的确认消息而超时,然后又会不断发送该数据分组造成死锁。

四次挥手为什么不能是三次呢?

当Client发送释放连接消息的时候,Server即使接收到了此消息,很有可能这个时候Server还有数据分组没有发送完毕,需要将剩下的数据分组发送完毕以后,才能发送释放连接的消息。所以这多出来的一次挥手就是将剩下的数据分组发送完毕。

四次挥手中2MSL是什么?

MSL是报文最大生存时间,2MSL就是2倍MSL的时间。
设置2MSL的目的主要是为了怕最后一个ask包对方没有收到,如果对方没有收到,对方会因为超时再次发送一个Fin包,主动关闭端收到以后会再次发送一个ask应答包。在TIME_WAIT状态时两端的端口不能使用,要等到2MSL时间结束才可继续使用。当连接处于2MSL等待阶段时任何迟到的报文段都将被丢弃。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值