TCP三次握手与四次挥手面试回答版本
面试官:说一下TCP三次握手的过程
参考面试回答:
-
在第一次握手的时候、客户端会随机生成初始化序号、放到TCP报文头部的序号字段中、同时把SYN标志设置为1 这样就表示SYN报文(这里是请求报文)。客户端将报文放入 TCP 报文首部的序列号字段中。接着把这个SYN报文发送给服务端、之后客户端处于
SYN_SENT
状态。这是第一次握手。 -
然后第二次握手的时候:服务端收到SYN报文后、首先服务端也会随机生成初始化序号、放到TCP报文头部的序号字段中、然后对客户端的初始化序号+1作为确认号、放到TCP报文头部的确认应答字段中、并将SYN和ACK标志设置为1,这样就表示SYN-ACK报文、然后把该报文发给客户端、之后服务端处于SYN_RCVD状态。这是第二次握手
-
最后来到第三次握手的过程:客户端收到服务端SYN-ACK报文后:客户端会回一个ACK确认报文、该报文的确认号是服务端的初始化序号+1、并且ACK标志会设置为1。表示这是一个确认报文。这是第三次握手
-
之后客户端处于ESTABLISHED状态。
-
服务端收到ACK确认报文后、服务端也进入处于
ESTABLISHED
状态。以上就是TCP三次握手的过程。
客户端 服务器| || SYN ----------------------> || |SYN_SENT || || <------ SYN-ACK ------------ || || ACK ----------------------> || |ESTABLISHED ESTABLISHED
为什么需要三次握手 两次不行吗
-
分析:面试的时候、最好说出两个原因,并且要解释一下为什么2次握手就不行。把面试官当做小白、讲到他理解这个问题的原因。
-
分析回答:
-
我的理解主要有两个原因:
-
第一个原因是、三次握手可以有效防止历史连接的建立、避免资源浪费。假设网络中残留一个序号为90的SYN报文、现在客户端向服务端发起了建立连接的请求、发送了一个序号为100的SYN报文、如果这时候服务端先收到的是序号为90的SYN报文、就代表收到了历史连接、这时候服务端会回复确认号为90+1的SYN-ACK报文、客户端收到后、发现其实自己期望收到的确认号是100+1、而不是90+1、所以会断开连接、并且回RST给服务端、服务端收到RST也就会断开连接了、这样就避免了历史连接的建立。
-
如果使用两次握手、服务器收到客户端的SYN报文后会立即建立连接。但服务器无法区分该SYN报文是新的连接请求、还是延迟到达的历史报文、如果收到的是历史SYN报文、服务器也会误以为是新的连接请求、并分配资源建立连接、造成资源浪费。这会导致服务器为无效的历史连接分配资源、造成浪费。
-
如果是三次握手
-
由于客户端收到的确认号是 91、与期望的 101 不符、客户端意识到这是一个历史连接的响应
-
客户端发送一个 RST 报文给服务器、告诉服务、这是一个错误的连接、请断开
-
服务器收到 RST 报文后、会断开连接、释放资源。
-
-
-
第二个原因是、三次握手可以确认客户端和服务端是否同时具备发送和接收的能力。第一次握手代表客户端具有发送能力、当服务端收到第一次握手并且响应了第二次握手、实际上这里就证明了服务端具有发送和接收的能力。客户端收到了第二次握手、然后响应了第三次握手、才代表客户端有接收的能力。如果是两次握手的话、只能证明服务端具有发送和接收能力、以及客户端的发送能力、但是无法证明客户端具有接收的能力。
-
三次握手的意义:
-
第一次握手 (SYN): 客户端发送 SYN 报文、表明客户端具有 发送 能力。
-
第二次握手 (SYN-ACK): 服务器收到 SYN 报文并回复 SYN-ACK 报文、表明服务器具有 接收 和 发送 能力。
-
第三次握手 (ACK): 客户端收到 SYN-ACK 报文并回复 ACK 报文、表明客户端具有 接收 能力。
-
通过三次握手可以确保客户端和服务端都具备双向通信的能力。
-
-
两次握手的缺陷: 两次握手只能确认服务器的发送和接收能力、以及客户端的发送能力、但无法确认客户端的接收能力。
-
以上就是我觉得TCP需要三次握手的原因。
参考面试回答:
我的理解主要有两个原因:
1.防止历史连接的建立、避免资源浪费
三次握手可以有效防止历史连接的建立、避免服务器为过期的连接分配资源。
在没有三次握手的情况下、服务器无法区分是新的连接请求还是之前连接的残留报文。
如果客户端发送了一个连接请求、服务器无法判断它是否是一个新的连接、可能会误以为这是一个有效的请求、进而分配资源。
但如果连接请求是历史报文、那么服务器响应客户端时、也就是客户端收到第二次握手的时候、客户端会发现确认号与预期不符、并会主动终止连接、发送 RST 报文通知服务器。这里也就是第三次握手的过程会发送一个RST重置报文给服务器。服务器收到 RST 报文后、会断开连接并释放资源。这样可以避免无效连接占用资源。
2.确保双方都具备发送和接收的能力
第二个原因是:三次握手可以确认客户端和服务端是否同时具备发送和接收的能力。第一次握手代表客户端具有发送能力、当服务端收到第一次握手并且响应了第二次握手、实际上这里就证明了服务端具有发送和接收的能力。客户端收到了第二次握手、然后响应了第三次握手、才代表客户端有接收的能力。如果是两次握手的话、只能证明服务端具有发送和接收能力、以及客户端的发送能力、但是无法证明客户端具有接收的能力。
介绍一下TCP四次挥手
分析:
-
问题:TCP四次挥手的过程
-
客户端FIN->服务端ACK ->服务端FIN ->客户端ACK
-
分析:要把每个阶段的TCP状态说出来。双方都都可以主动断开连接,下图是客户端主动断开连接的过程:
-
客户端打算关闭连接、此时会发送一个
FIN
报文、之后客户端进入FIN_WAIT_1
状态。 -
服务端收到FIN报文后、就向客户端发送ACK应答报文、接着服务端进入
CLOSE_WAIT
状态。 -
客户端收到服务端的ACK应答报文后、之后进入
FIN_WAIT_2
状态。 -
等待服务端处理完数据后、也向客户端发送FIN报文、之后服务端进入
LAST_ACK
状态。 -
客户端收到服务端的FIN报文后、回一个
ACK
应答报文、之后进入TIME_WAIT
状态。 -
服务端收到了ACK应答报文后、就进入了
CLOSE
状态、至此服务端已经完成连接的关闭。 -
客户端在
TIME_WAIT
状态经过2MSL一段时间后、自动进入CLOSE
状态、至此客户端也完成连接的关闭。
-
-
总结:以上就是四次挥手的过程、每个方向都需要一个
FIN
和一个ACK
、因此通常被称为四次挥手。
参考面试回答:
-
第一次挥手:客户端打算关闭连接、此时会发送一个FIN报文、用来关闭客户端到服务端的数据传送、并进入
FIN_WAIT_1
状态。 FIN报文会携带一个序列号。 -
第二次挥手: 服务端收到FIN报文后、就向客户端发送ACK应答报文、确认收到了客户端的关闭请求。 ACK报文会携带确认序列号、表示服务端已经正确接收了客户端发送的FIN报文。 服务端进入
CLOSE_WAIT
状态。 -
客户端收到服务端的ACK应答报文后、进入
FIN_WAIT_2
状态、等待服务端发送FIN报文。此时、客户端到服务端的连接已经释放、客户端不再发送数据、但服务端仍然可以向客户端发送数据。 -
第三次挥手: 等服务端处理完数据后、也向客户端发送
FIN
报文、用来关闭服务端到客户端的数据传送、并进入LAST_ACK
状态。 -
第四次挥手: 客户端收到服务端的FIN报文后、回一个
ACK
应答报文、确认收到了服务端的关闭请求。 客户端进入TIME_WAIT
状态。 -
服务端收到了ACK应答报文后、就进入了
CLOSE
状态、至此服务端已经完成连接的关闭。 -
客户端在
TIME_WAIT
状态经过2MSL(Maximum Segment Lifetime)一段时间后、自动进入CLOSE
状态、至此客户端也完成连接的关闭。