TCP的三次握手,四次挥手(不看后悔,一看必懂)

版权声明:本文为博主原创文章,未经博主允许可以转载。 https://blog.csdn.net/qq_36071795/article/details/83784747

三次握手

step1:第一次握手

客户端发送数据包到服务器,(在此连接请求报文段中的同步位SYN=1,确认ACK=0,表示这是一个TCP连接请求数据报文,序号seq=x,表示传输数据时的起始序号是x)此时,客户端进入SYN_SENT状态,等待服务器确认

step2:第二次握手

服务器收到连接请求报文段后,若同意建立连接,则向客户端发送确认报文段。此时服务器进入SYN_RECV状态。(其中确认报文段中,标识位SYN=1,ACK=1,表示这是一个TCP连接响应数据报文,并含服务端的初始序号seq(服务器)=y,以及服务器对客户端初始序号的确认号ack(服务器)=seq(客户端)+1=x+1)。

step3:第三次握手

客户端再次向服务器发送一个序列号(seq=x+1),确认号为ack(客户端)=y+1,此包发送完毕,客户端和服务器进入ESTAB_LISHED(TCP连接成功)状态,完成三次握手。

常见面试题:

1.为什么需要三次握手,两次不可以吗?或者四次、五次可以吗? 
我们来分析一种特殊情况,如果是两次握手,假设服务器给客户端在第二次握手时发送数据,数据从服务器发出,服务器认为连接已经建立,但在发送数据的过程中数据丢失,客户端认为连接没有建立,会进行重传。假设每次发送的数据一直在丢失,客户端会一直向服务器发送请求连接,服务器就会产生多个无效连接,占用资源,这个时候服务器可能会挂掉。这个现象就是我们听过的“SYN的洪水攻击”。

四次挥手

四次挥手过程(关闭客户端到服务器的连接)

step1:第一次挥手

首先,客户端发送一个FIN,用来关闭客户端到服务器的数据传送,然后等待服务器的确认。其中终止标志位FIN=1,序列号seq=u。

step2:第二次挥手

服务器收到这个FIN,它发送一个ACK,确认ack为收到的序号加一。

step3:第三次挥手

关闭服务器到客户端的连接,发送一个FIN给客户端。

step4:第四次挥手

客户端收到FIN后,并发回一个ACK报文确认,并将确认序号seq设置为收到序号加一。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。

客户端发送FIN后,进入终止等待状态,服务器收到客户端连接释放报文段后,就立即给客户端发送确认,服务器就进入CLOSE_WAIT状态,此时TCP服务器进程就通知高层应用进程,因而从客户端到服务器的连接就释放了。此时是“半关闭状态”,即客户端不可以发送给服务器,服务器可以发送给客户端。
此时,如果服务器没有数据报发送给客户端,其应用程序就通知TCP释放连接,然后发送给客户端连接释放数据报,并等待确认。客户端发送确认后,进入TIME_WAIT状态,但是此时TCP连接还没有释放,然后经过等待计时器设置的2MSL后,才进入到CLOSE状态。

为什么客户端在TIME-WAIT状态需要等待2MSL时间?

 

首先,MSL即Maximum Segment Lifetime,就是最长报文段寿命,是任何报文在网络上的存在的最长时间,超过这个时间报文将被丢弃。《TCP/IP详解》中是这样描述的:MSL是任何报文段被丢弃前在网络内的最长时间。RFC 793中规定MSL为2分钟,实际应用中常用的是30秒、1分钟、2分钟等。

TCP的TIME_WAIT需要等待2MSL,当TCP的一端发起主动关闭,三次挥手完成后发送第四次挥手的ACK包后就进入这个状态,等待2MSL时间主要目的是:防止客户端发送给服务器的最后一个ACK包对方没有收到,那么对方在超时后将重发第三次握手的FIN包,主动关闭端接到重发的FIN包后可以再发一个ACK应答包。

为什么是四次挥手,而不是三次或是五次、六次?

双方关闭连接要经过双方都同意。所以,首先是客服端给服务器发送FIN,要求关闭连接,服务器收到后会发送一个ACK进行确认。服务器然后再发送一个FIN,客户端发送ACK确认,并进入TIME_WAIT状态。等待2MSL后自动关闭。

猜你喜欢

转载自blog.csdn.net/qq_36071795/article/details/83784747
今日推荐