当前位置: 首页 > java >正文

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、因此通常被称为四次挥手。

参考面试回答:

  1. 第一次挥手:客户端打算关闭连接、此时会发送一个FIN报文、用来关闭客户端到服务端的数据传送、并进入FIN_WAIT_1状态。 FIN报文会携带一个序列号。

  2. 第二次挥手: 服务端收到FIN报文后、就向客户端发送ACK应答报文、确认收到了客户端的关闭请求。 ACK报文会携带确认序列号、表示服务端已经正确接收了客户端发送的FIN报文。 服务端进入CLOSE_WAIT状态。

  3. 客户端收到服务端的ACK应答报文后、进入FIN_WAIT_2状态、等待服务端发送FIN报文。此时、客户端到服务端的连接已经释放、客户端不再发送数据、但服务端仍然可以向客户端发送数据。

  4. 第三次挥手: 等服务端处理完数据后、也向客户端发送FIN报文、用来关闭服务端到客户端的数据传送、并进入LAST_ACK状态。

  5. 第四次挥手: 客户端收到服务端的FIN报文后、回一个ACK应答报文、确认收到了服务端的关闭请求。 客户端进入TIME_WAIT状态。

  6. 服务端收到了ACK应答报文后、就进入了CLOSE状态、至此服务端已经完成连接的关闭。

  7. 客户端在TIME_WAIT状态经过2MSL(Maximum Segment Lifetime)一段时间后、自动进入CLOSE状态、至此客户端也完成连接的关闭。

http://www.xdnf.cn/news/1275.html

相关文章:

  • 自然语言处理 | 语言模型(LM) 浅析
  • spark-sql
  • 2023蓝帽杯初赛内存取证-5
  • springBoot_项目目录结构
  • 刀客doc:快手磁力引擎副总裁冯超离职,王志强接管渠道业务
  • 仅追加KV数据库
  • C# 跨进程 临界区 互斥 进程锁
  • 航电系统之自动控制系统篇
  • 词语关系图谱模型
  • Python中__init__方法的深度解析:构造对象的艺术
  • Milvus(3):数据库、Collections说明
  • 将Ubuntu系统中已有的Python环境迁移到Anaconda的虚拟环境中
  • 物联网赋能玻璃制造业:实现设备智能管理与生产协同
  • C++ 哈希表
  • WebGL名词解释——裁剪空间
  • N8N MACOS本地部署流程避坑指南
  • CAN总线接口卡有什么优势
  • Linux 云服务器零基础指令扫盲
  • L1-6、Prompt 与上下文的关系[特殊字符]
  • Node.js技术原理分析系列8——将Node.js内置模块外置
  • CS61A:SCHEME LIST
  • 从零学会epoll的使用和原理
  • 「平方根的算法对决:二分查找 vs. 牛顿迭代法」
  • Spark 与 Hadoop:对比与联系
  • AI编程之Nodejs+MYSQL写一个爬虫系统
  • Python数据分析与机器学习实战:从数据到洞察的完整路径
  • vue中将elementUI和echarts转成pdf文件
  • 【DeepSeek 学习推理】Llumnix: Dynamic Scheduling for Large Language Model Serving实验部分
  • TM2SP-Net阅读
  • 日本电网的特点及分布地图