TCP三次握手,四次挥手详解以及相关面试问题

TCP 三次握手

TCP三次握手图解:

在这里插入图片描述

TCP三次握手概述:

首先要明白两次握手是必须的,如果只有一次握手,无法建立可靠的连接,因为并不知道另一方有没有收到信息,所以两次握手是必须的。

1.第一次握手客户端向服务器发送请求,服务器接收到请求
客户端 ——> 服务端 : SYN = 1 , seq = x

SYN = 1 代表同步请求,seq则是发送的序列号(必须发送序列号,因为序列号可以避免因网络延迟带来的信号混乱)

2.第二次握手服务器接受请求,向客户端发送同步信号
服务端 ——> 客户端: SYN = 1, ACK = 1, seq = y, ack = x + 1

SYN = 1 代表同步请求,seq代表服务端发出报文段的序列号,ack则是确认号(确认号只有在 ACK = 1 的情况下才有效).
SYN = 1 , ACK = 1代表这是对客户端发来的同步请求的回复

3.第三次握手客户端向服务器发送准备完成信号
客户端 ——> 服务端: ACK = 1, seq = x + 1 , ack = y + 1

此时的 SYN = 0, 说明此信号已经不是同步请求,而是互相传送数据的确认,第三次握手可以避免因网络延时问题造成的服务器空等待,也可以避免第二次握手信号丢失导致服务器错误传输数据。


TCP 四次挥手

TCP四次挥手图解:

在这里插入图片描述

TCP四次挥手概述:

TCP关闭连接必须是可靠的,也就是让客户端和服务端都可靠的关闭连接。

如果只有一次挥手客户端就直接关闭,那么可能数据还没有传输完成,服务器还有可能空等待

如果是两次挥手数据也可能没有传完

如果是三次挥手这一次的挥手可能丢失,这样服务器虽然正常关闭,但是客户
端却一直空等待,认为服务器还在传数据

第四次挥手可以防止第三次挥手的信号丢失

等待2ML客户端第四次挥手后等待2MSL, 可以防止第四次挥手信号的丢失

四次挥手分析:

1.第一次挥手客户端告知服务器,自己传输完成,让服务器关闭
客户端 ——> 服务端: seq = u, FIN = 1

2.第二次挥手服务器得知客户端将结束连接,返回确认消息,并持续传送最后的数据
服务端 ——> 客户端: seq = v, ACK = 1, ack = u + 1

3.第三次挥手服务器将最后的数据传送完成,向客户端发送确认消息,让客户端关闭
服务端 ——> 客户端: seq = w, FIN = 1, ACK = 1, ack = u + 1

4.第四次挥手客户端收到消息,等待2MSL之后,如果没有服务端重发的ACK消息,自己就关闭
客户端 ——> 服务端: seq = u + 1, ACK = 1, ack = w + 1

TCP的四次挥手在本质上都是为了让客户端与服务器正常的关闭。

那么为什么客户端需要等待2MSL再关闭
因为服务端可能没有收到最后一次发来的ACK,那么他就不会关闭,这样客户端提前关闭了,服务端却一直再运行消耗着资源。
让客户端等待2MSL再关闭,如果期间服务端没有收到最后一次发来的ACK,那么会有超时重传机制,也就是相当于重新进行第三次挥手,那么客户端在2MSL的时间内也回重新收到ACK,然后再一次进行第四次挥手让服务器关闭

注意:服务端在进行第三次挥手后,立刻会启动超时重传机制;客户端在发出第四次挥手后,立刻就会启动2MSL的等待


TCP三次握手,四次挥手常见面试问题:

1.为什么连接的时候是三次握手,关闭的时候却是四次握手?(为什么握手需要四次?

主要是因为关闭连接时,像比于建立连接时可能会有数据还没有传输完成的情况。如果只有三次挥手,第三次挥手信号如果因网络延迟丢失,此时服务器已经关闭,而客户端还认为还有数据没有传完,仍在等待

2.为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?

如果不等待2MSL客户端就直接结束, 第四次挥手信号丢失,服务端将会一直等待;让客户端等待2MSL时间,即便是第四次挥手信号丢失,服务端也会开启超时重传机制,重新发送第三次挥手的信号(2MSL的时间可以让信号丢失的情况下,超时重传机制重新发的信号也能够到达)。

3.为什么不能用两次握手进行连接?

如果只有两次握手,如果第二次握手的信号丢失,那么客户端将不知道是否已经连接上服务端,会形成死锁

4.如果已经建立了连接,但是客户端突然出现故障了怎么办?

服务端会有一个超时关闭机制,如果限定时间内没有接收到客户端的数据传送,那么就认为客户端已经出现故障, 服务器自动断开