三次握手和四次挥手

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了三次握手和四次挥手相关的知识,希望对你有一定的参考价值。

参考技术A

三次握手的流程图:

在网络数据传输中,传输层协议TCP(传输控制协议)是建立连接的可靠传输,TCP建立连接的过程,我们称为三次握手。

第一次,客户端向服务器发送SYN同步报文段,请求建立连接
客户端发送网络包,服务端收到了。
这样服务端就能得出结论:客户端的发送能力、服务端的接收能力是正常的。

第二次,服务器确认收到客户端的连接请求,并向客户端发送SYN同步报文,表示要向客户端建立连接
服务端发包,客户端收到了。
这样客户端就能得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的。不过此时服务器并不能确认客户端的接收能力是否正常。

第三次,客户端收到服务器端的确认请求后,处于建立连接状态,向服务器发送确认报文
客户端发包,服务端收到了。
这样服务端就能得出结论:客户端的接收、发送能力正常,服务器自己的发送、接收能力也正常。

因此,需要三次握手才能确认双方的接收与发送能力是否正常。

无法确认客户端的接收能力。
假设第二次握手的报文丢失了,或者是说有人恶意向服务器不断发送SYN同步报文(SYN洪水)。那么服务器端就会有大量的无效连接,服务器处理连接的数量是有限的,当有大量的无效连接建立后,服务器处理有效连接是能力就会受限,且建立连接会消耗大量是资源,至此有可能导致服务器崩溃。

因为三次已经足够确认双方的发送和接收的能力了,四次以及四次以上当然就没必要啦

可以,但是只有第三次,此时的established状态相对安全并且够确认服务器的接收发送能力。但是,第一次、第二次握手不可以携带数据

为什么这样呢?大家可以想一个问题,假如第一次握手可以携带数据的话,如果有人要恶意攻击服务器,那他每次都在第一次握手中的 SYN 报文中放入大量的数据。因为攻击者根本就不理服务器的接收、发送能力是否正常,然后疯狂着重复发 SYN 报文的话,这会让服务器花费很多时间、内存空间来接收这些报文。

也就是说,第一次握手不可以放数据,其中一个简单的原因就是会让服务器更加容易受到攻击了。而对于第三次的话,此时客户端已经处于 ESTABLISHED 状态。对于客户端来说,他已经建立起连接了,并且也已经知道服务器的接收、发送能力是正常的了,所以能携带数据也没啥毛病。

服务器第一次收到客户端的 SYN 之后,就会处于 SYN_RCVD 状态,此时双方还没有完全建立其连接,服务器会把此种状态下请求连接放在一个队列里,我们把这种队列称之为半连接队列。

当然还有一个全连接队列,就是已经完成三次握手,建立起连接的就会放在全连接队列中。如果队列满了就有可能会出现丢包现象。

SYN Flood 属于典型的 DoS/DDoS 攻击。其攻击的原理很简单,就是用客户端在短时间内伪造大量不存在的 IP地址,并向服务端疯狂发送SYN。对于服务端而言,会产生两个危险的后果:

处理大量的SYN包并返回对应ACK, 势必有大量连接处于SYN_RCVD状态,从而占满整个半连接队列,无法处理正常的请求。
由于是不存在的 IP,服务端长时间收不到客户端的ACK,会导致服务端不断重发数据,直到耗尽服务端的资源。

增加 SYN 连接,也就是增加半连接队列的容量。
减少 SYN + ACK 重试次数,避免大量的超时重发。
利用 SYN Cookie技术,在服务端接收到SYN后不立即分配连接资源,而是根据这个SYN计算出一个Cookie,连同第二次握手回复给客户端,在客户端回复ACK的时候带上这个Cookie值,服务端验证Cookie 合法之后才分配连接资源。

下面来看看四次挥手的流程图:

中断连接端可以是客户端,也可以是服务器端。

不像建立连接的过程,服务器端在调用了accept()之后,剩下的都交给内核来处理,用户空间不用做什么,断开连接是,A端调用close()关闭文件描述符后,A端就停止发送数据了进行发送,B端收到后结束报文段之后,的得知A端要断开连接了,但是B端可能有自己还没有处理完的数据,不能立即断开连接,就要先给出回复,表示自己已经收到消息了,然后将自己的数据处理完之后,可以断开连接的时候,再调用close()发出断开连接请求,在收到A端的确认回复之后,断开连接,一共需要四次挥手。

MSL是 最长报文段寿命,它是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。
2MSL等待状态:它是任何报文段被丢弃前在网络内的最长时间。

(1)保证客户端发送的最后一个ACK报文段能够到达服务端。

(2)防止“已失效的连接请求报文段”出现在本连接中。
客户端在发送完最后一个ACK报文段后,再经过2MSL,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失,使下一个新的连接中不会出现这种旧的连接请求报文段。

上面是一方主动关闭,另一方被动关闭的情况,实际中还会出现同时发起主动关闭的情况,
具体流程如下图:

参考资料:
一篇文章带你熟悉 TCP/IP 协议
「计算机网络」前端必备知识,看到就是赚到系列(上)
什么是三次握手、四次挥手
面试官,不要再问我三次握手和四次挥手

TCP三次握手和四次挥手

1.TCP报文

在这里插入图片描述
1.序号:Seq(Sequence Number)序号占32位,用来标识从计算机A发送到计算机B的数据包的序号,计算机发送数据时对此进行标记。

2.确认号:Ack(Acknowledge Number)确认号占32位,客户端和服务器端都可以发送,Ack = Seq + 1。

3.标志位:每个标志位占用1Bit,共有6个,分别为 URG、ACK、PSH、RST、SYN、FIN;--------- URG:紧急指针是否有效。为1,表示某一位需要被优先处理。-----ACK:确认号是否有效,一般置为1.------PSH:提示接收端应用程序立即从TCP缓冲区把数据读走。------PST:对方要求重新建立连接,复位。------SYN:请求建立连接,并在其序列号的字段进行序列号的初始值设定,建立连接。------FIN:希望断开连接。

2.三次握手

2.1三次握手的目的

为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。

客户端发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达服务器。

本来这是一个早已失效的报文段。但服务器收到此失效的连接请求报文段后,就误认为是客户端再次发出的一个新的连接请求。于是就向客户端发出确认报文段,同意建立连接。

客户端不会向服务器的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。

2.2三次握手的过程

在这里插入图片描述

一:第一次握手
客户端执行connect函数,向服务器发送连接请求报文段,此时TCP报文首部的同步位SYN=1,这时客户端进入SYN_SENT-同步已发送状态,等待服务器的确认。
二:第二次握手
服务器收到请求报文段后,若同意建立连接,则向客户端发送确认,在确认报文段中SYN=1,ACK=1。这时服务器进入了SYN_RCVD(同步收到) 状态,客户端进入ESTABLISHED状态。
三:第三次握手
客户端在收到服务器的确认信息后,还要给服务器发出确认,确认报文段将ACK置1,TCP连接已经建立服务器都进入ESTABLISHED状态。

三次握手完成后服务器就知道了客户端发送数据的序列号,客户端也知道服务器发送数据的序列号。

3.四次挥手

3.1四次挥手的目的

TCP的连接是双向的,故在四次挥手中,前两次挥手用于断开一个方向的连接,,后两次挥手用于断开另一个方向的连接。

3.2四次挥手的过程

一:第一次挥手
客户端进程先向TCP发出链接释放报文段,并且停止发送数据,主动关闭TCP连接。连接释放报文段首部FIN=1.客户端进入FIN_WAIT_1状态。
二:第二次挥手
服务器收到连接释放报文段后立即发出确认,把确认报文段首部ACK置为1,后服务器进入等待关闭状态。客户端收到服务器的确认后。进入终止等待状态,等待服务器发出的连接释放报文段。
此时的TCP连接处于半关闭状态,即客户端已经没有数据要发送了,但服务器如果要发送数据,客户端还要接收数据。故服务器到客户端这个方向的连接并没有关闭。
三:第三次挥手
如果服务器没有要向客户端发送的数据了,其应用进程就通知TCP释放连接,这时服务器发出的连接释放报文段需要使FIN=1,这时服务器就进入了最后确认状态,等待客户端的确认。
四:第四次挥手
客户端在收到服务器的连接释放报文后,需要对此发出确认。在确认报文中将ACK置为1.然后客户端进入 时间等待 状态。

注意:
1.第四次挥手完成后,TCP连接还没有完全释放掉,必须经过时间等待计时器设置的2MSL后,客户端才进入关闭状态。 MSL称为 最长报文段寿命,即报文段存活的最长时间。
2.服务器收到客户端的确认报文过后就会立即进入 关闭 状态。服务器的结束TCP要比客户端早一些。

以上是关于三次握手和四次挥手的主要内容,如果未能解决你的问题,请参考以下文章

三次握手和四次挥手

一文搞懂TCP的三次握手和四次挥手

图解TCP的三次握手和四次挥手(简单明了)

TCP的三次握手和四次挥手

三次握手&&四次挥手

三次挥手?说好的四次挥手呢?(顺带解释三次握手和四次挥手)