TCP三次握手与四次挥手:推荐学习资料、过程详解、面试相关题与回答模板(为什么不是两次握手等精讲)

news2024/11/18 17:21:56

推荐资料(建议按照顺序先都看完,再看本篇文章)

https://www.bilibili.com/video/BV18h41187Ep/
https://www.bilibili.com/video/BV1at4y1Q77b/
https://bbs.huaweicloud.com/blogs/277728
https://blog.csdn.net/dreamispossible/article/details/91345391
小林coding计网p242-302(看不完就算了,其实这个有些地方讲得太细了,面试不会考那么细……的吧?/(ㄒoㄒ)/~~)

过程

三次握手和四次挥手图解

(图的原出处忘了,应该是来自小林coding计网)
在这里插入图片描述

SYN包/ACK包格式

在这里插入图片描述

为什么tcp需要三次握手,不能是两次?

正常两次握手的流程

首先我们要思考,如果为两次握手,正常连接的情况是什么样子的。
由于只有两次,那么服务端在接收到SYN报文后就会建立established状态。客户端在接收到SYN和ACK报文后,也会建立established状态。
在这里插入图片描述
如果说三次握手相当于:
客户端:我有个重要信息想和你说(SYN),你有空吧?
服务端:我有空(ACK),我刚好也有个重要信息想和你说,我们现在就聊,你有空吧?(SYN)
客户端:我也有空捏(ACK)。
【随后客户端和服务端都开始讲话。】

真是一场酣畅淋漓的奔赴啊(泪目),可以看到三次握手就是非常谨慎地确保接下来双方 都能 立马 双向通信。

而二次握手就相当于:
客户端:我有个重要信息想和你说(SYN),你有空吧?
服务端:我有空(ACK),我刚好也有个重要信息想和你说,我们现在就聊,你有空吧?(SYN)
【随后服务端立马开始讲它想说的重要信息。】

这种情况会导致两个问题。首先,实际上服务端并不能确保客户端的接受能力是否正常(就是例子中的是否立马有空听他讲话),其次,更重要的,就是历史连接的初始化问题。

确保双方的发送、接收能力正常

在这里插入图片描述

历史连接的初始化

什么叫历史连接的初始化呢?

考虑一个场景:由于通常情况客户端都会连续发送多次 SYN 报文建立不同的连接。
因为网络拥堵、客户端短暂宕机等因素从而导致 一个「旧 SYN 报文」比「最新的 SYN 」 报文早到达了服务端。因为只有两次握手。那么服务端会立马进入established状态,并且开始发送数据。

比喻成我上文的聊天的话,就是同时存在客户端A要跟服务端C讲重要信息1,服务端C也要和客户端A讲重要信息2。客户端B要跟服务端C讲重要信息3,服务端C也要和客户端B讲重要信息4。
在这里插入图片描述
如果是三次握手,则是
客户端A:你好我有个重要信息1想和你说(SYN),你有空吧?【但是这个消息没有发出去】
客户端B:我有个重要信息3想和你说(SYN),你有空吧?【但是这个消息还没有被客户端接收】
客户端A:我有个重要信息1想和你说(SYN),你有空吧?【此时发给了服务端】
服务端:我有空(ACK),我刚好也有个重要信息2想和你说,我们现在就聊,你有空吧?(SYN)【和A试图建立连接】
此时因为上文是客户端B,所以是B接收该消息。
客户端B:你在说啥呢。听不懂,先不跟你聊了。(RST)
此时服务端就知道客户端A没空,因为他没有收到客户端A的ACK包。(和A的连接中止)
客户端B:我有个重要信息3想和你说(SYN),你有空吧?【此时发给了服务端】
服务端:我有空(ACK),我刚好也有个重要信息4想和你说,我们现在就聊,你有空吧?(SYN)
客户端B:我有空(ACK)。
随后客户端B和服务端都开始讲话。

如果是两次握手,则是
客户端A:我有个重要信息1想和你说(SYN),你有空吧?【但是这个消息没有发出去】
客户端B:我有个重要信息3想和你说(SYN),你有空吧?【但是这个消息还没有被客户端接收】
客户端A:我有个重要信息1想和你说(SYN),你有空吧?【此时发给了服务端】
服务端:我有空(ACK),我刚好也有个重要信息2想和你说,我们现在就聊,你有空吧?(SYN)【和A试图建立连接】
随后服务端立马开始讲它想说的重要信息2。此时因为上文是客户端B,所以是B接收该消息。
客户端B:你在说啥呢。听不懂,先不跟你聊了。(RST)
随后服务端闭嘴了。(和A的连接中止)
客户端B:我有个重要信息3想和你说(SYN),你有空吧?【此时发给了服务端】
【随后服务端立马开始讲它想说的重要信息4。此时因为上文是客户端B,所以是B接收该消息。】
随后客户端B和服务端都开始讲话。

(图的原出处应该来自小林coding,但是网上找不到原图了)
在这里插入图片描述
所以可以看到,三次握手和两次握手相比,不会让服务端多建立一个历史连接,即多一个established状态,还让服务端白发送数据,从而浪费服务端的资源。

无法同步双方初始序列号

除了避免历史连接的初始化之外,三次握手还有一个重要作用。就是同步双方的初始序列号。

序列号在TCP连接中扮演了重要角色,它具有以下作用:
● 接收方可以消除重复的数据,确保数据的准确性。
● 接收方可以按照序列号的顺序接收数据包,保证数据的完整性。
● 序列号可以标识已经被对方接收的数据包,实现可靠的数据传输。

因此,在建立TCP连接时,客户端发送带有初始序列号的SYN报文,并需要服务器回复一个ACK报文,表示成功接收了客户端的SYN报文。然后,服务器发送带有初始序列号的SYN报文给客户端,并等待客户端的应答,这样一来一回,才能确保双方的初始序列号能够可靠地同步。

总结

三次握手不能为两次的主要原因为:

  • 三次握手保证了双方都知道自己和对方具有接收和发送能力。
  • 三次握手才可以阻止历史连接的初始化。(主要原因)
  • 三次握手才可以同步双方的初始序列号。

面试相关题与回答

请简述下tcp三次握手?

以下回答背熟大概用时2min。

TCP协议属于传输层的重要协议之一,主要负责端到端的沟通。假设我们现在有一个客户端和一个服务端要进行通信。
服务端是一种被动通信的角色,当它启动后,会开放自己的一些端口并等待客户端连接。客户端是一种主动通信的角色,当它启动后,会主动连接指定ip地址的服务端。
假设此时两个端都已经启动,服务端开放了端口a,处于listen的状态。

  • 客户端主动发起请求连接,生成一个初始化序列号ISN为x,并传输一个syn包给服务端。syn为synchronization,表示同步的意思,同时值为x。随后客户端便处于syn_sent状态。这就是第一次握手。
  • 服务端收到syn包后,也生成一个初始化序列号ISN为y,并传输一个ack包和一个syn包给客户端。ack为acknowledge,表示接受的意思,在这里表示成功接收,同时值为第一次握手时客户端的序列号+1。随后服务端便处于syn_recv(syn_recieved)状态。这就是第二次握手。
  • 客户端收到ack包和syn包后,便处于established状态。且会再传输一个ack包给回服务端,值为第二次握手时服务端的序列号y+1。服务端接收该包后便也处于estabished状态。这就是第三次握手。

综上,三次握手实际上就是一个建立连接的过程,在三次握手结束之后,客户端和服务端就可以通过该端口相互通信,传输数据了。

请简述下tcp四次挥手?

以下回答背熟大概用时2min。

TCP协议属于传输层的重要协议之一,主要负责端到端的沟通。tcp四次挥手实际上就是两端之间结束通信的过程。假设我们现在有一个客户端和一个服务端要断开连接,理论上任意一方都有主动断开的权利。但通常情况下是客户端主动断开连接。

  • 那么客户端就会生成一个序列号x,并发送一个fin包和一个ack包给服务端。fin表示finish,结束的意思。fin包中携带了x的值。此时客户端处于fin_wait1状态。这就是第一次挥手。
  • 服务端收到fin包和ack包后,便处于close_wait的状态,就是等待关闭的意思。同时发送一个ack包给回客户端,ack表示acknowledge,接收的意思,值为第一次挥手时客户端的序列号+1。客户端在接收到该ack包后就处于fin_wait2状态。这就是第二次挥手。
  • 同时,服务端可能存在一些数据还需要传送给客户端。等他传输完毕,确认要断开连接时,会生成一个序列号y,并发送一个fin包给客户端。此时服务端处于last_ack状态。这就是第三次挥手。
  • 客户端接收到服务端的fin包,便发送一个ack包给回服务端,值为第三次挥手时服务端的序列号+1。此时客户端处于time_wait状态,也就是等待关闭。一定时长后,服务端收到了ack包,客户端和服务端才会进入closed状态。这就是第四次挥手。

tcp三次握手时可以带数据吗?第几次握手带数据呢?

背熟以下回答,大概用时半分钟。

tcp的第三次握手时可以携带应用数据。因为此时客户端已经在前两次握手时确认了自己的接收和发送能力没有问题。也知道了服务端的接收和发送能力没有问题。第三次握手只是需要让服务端知道客户端的接受能力没有问题。所以可以将ACK报文和数据一同传输过去。

如果tcp第三次握手时的ACK报文丢失,会发生什么?

背熟以下回答,大概用时半分钟。

如果第三次握手时的ACK报文丢失,就相当于服务端依旧只能处于syn_recv状态。但是依旧可以建立连接并正常接收数据。因为数据中也会有ACK标识位,值和丢失的ACK报文的值是一样的。

为什么tcp需要三次握手,不能是两次握手?

背熟以下回答,大概用时两分半。

以最经典的客户端和服务端建立连接举例,三次握手不能为两次的原因为:

  • 第一,三次握手保证了双方都知道自己和对方具有接收和发送能力。
  • 第二,也就是最重要的理由,三次握手才可以阻止历史连接的初始化。
  • 第三,三次握手才可以同步双方的初始序列号。

第一个原因很好理解,因为第三次握手为客户端向服务端发送ACK报文,省去了这个步骤,服务端收不到客户端的ACK报文,就无法得知客户端是否有正常接收的能力。

那么什么叫历史连接的初始化呢?
我们考虑一个场景:通常情况客户端都会连续发送多次 SYN 报文建立不同的连接。如果因为网络拥堵、客户端短暂宕机等因素从而导致 一个「旧 SYN 报文」比「最新的 SYN 」 报文早到达了服务端。因为只有两次握手。那么服务端会立马进入established状态,并且开始发送数据。
客户端根据上下文,对比序列号后,发现不是它想要接收的信息。便会发送RST报文,使得服务端的连接中止。之后最新的SYN报文到达时,再继续第二次握手和第三次握手,从而成功建立连接。
在这过程中,相较于三次握手,二次握手的服务端多了一个由旧SYN报文引起的established状态,这就是历史连接的初始化。二次握手无法避免历史连接的初始化,还让服务端白发送数据,从而浪费服务端的资源。

最后,序列号在TCP连接中扮演了重要角色,它确保了数据的准确性、完整性。且可以表示哪些数据包是被对方接受过的。三次握手才可以同步双方的初始序列号,从而实现TCP可靠传输。

为什么tcp需要三次握手,不能是四次握手?

背熟以下回答,大概用时半分钟。

以最经典的客户端和服务端建立连接举例,其实tcp可以是四次握手。将原有的三次握手中的第二步,服务端接收到客户端的SYN报文后,发送ACK报文和SYN报文给客户端,拆分为两步,分别发送ACK报文和SYN报文即可。但是基于最优法则,将这两步合为一步。

为什么每次tcp连接时,初始化的序列号都要求不一样呢?

背熟以下回答,大概用时半分钟。

假设每次tcp连接时的初始化序列号都一样。那么就很大概率遇到历史报文的序列号在对方的接收窗口内的情况,从而导致历史报文被新连接成功接收,造成数据错乱。为此,初始化序列号ISN是基于时钟随机生成的,但这并不能完全避免上述问题,因为序列号会回绕,所以还需要用时间戳的机制来判断历史报文。此外,如果初始化序列号都一样的话,很容易被黑客伪造相同序列号的tcp报文用于攻击。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1283300.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

paddleocr文本检测改进变迁

数据增强: BDA(Base Data Augmentation):色调变换,透明度变换,旋转,背景模糊,饱和度变换。 图像变换类:AutoAugment,RandAugment 图像裁剪类:CutOut、RandErasing、Hi…

【UE5】使用场系统炸毁一堵墙

效果 步骤 1. 新建一个空白项目 2. 新建一个Basic关卡,然后添加一个第三人称游戏和初学者内容包到内容浏览器 3. 在场景中添加一堵墙 4. 选项模式选择“破裂” 点击新建 新建一个文件夹用于存储几何体集 点击“统一” 最小和最大Voronoi点数都设置为100 点击“破…

【java设计模式】——代理设计模式,两种举例说明

代理设计模式 1.介绍 Spring 框架中AOP底层使用动态代理设计模式。通过学习动态代理设计模式可以很好的理解Spring框架AOP底层 代理模式(Proxy)是GoF23种设计模式之一。所谓代理模式是指客户端并不直接调用实际的对象,而是通过调用代理&am…

Web APIs—介绍、获取DOM对象、操作元素内容、综合案例—年会抽奖案例、操作元素属性、间歇函数、综合案例—轮播图定时器版

版本说明 当前版本号[20231204]。 版本修改说明20231204初版 目录 文章目录 版本说明目录复习变量声明 Web APIs - 第1天笔记介绍概念DOM 树DOM 节点document 获取DOM对象案例— 控制台依次输出3个li的DOM对象 操作元素内容综合案例——年会抽奖案例操作元素属性常用属性修改…

天池XGBoost,重写柱状图代码

天池XGBoost 地址 重写柱状图代码:我没考虑复杂度,只考虑直观理解 原文统计地点是否降雨来画柱状图实在是太麻烦了,我重写了一下。最麻烦的就是数据处理。我的思路是: 首先取下雨的全部数据data[data[RainTomorrow] Yes] 然后…

全网最牛最“刑”的Fiddler移动端抓包

本篇文章,博主想使用通俗易懂的话语,让大家明白以下内容: 什么是抓包哪些场景需要用到抓包Fiddler抓包的原理怎样使用Fiddler进行移动端抓包 抓包 包 (Packet) 是TCP/IP协议通信传输中的数据单位,一般也称“数据包”。 我们平常…

二维码智慧门牌管理系统升级:轻松解决重新制牌问题

文章目录 前言一、更便捷的申请方式二、系统优势 前言 随着科技的快速发展,智能化管理已经成为我们日常生活的一部分。最近,为了满足人们对门牌类型更换、门牌丢失等需要重新制牌的需求,二维码智慧门牌管理系统升级了解决方案,为…

Python如何从文件中读取数据

从文件中读取数据 1. 读取整个文件 要读取文件,首先来创建一个文件: 然后打开并读取这个文件,再将其内容显示到屏幕上: file_reader.py with open(pi_digits.txt) as file_object:contents file_object.read()print(contents)…

创新、升级丨数据手套FOHEART Pro开启手势识别新篇章!

在人机交互领域,我们始终追求更加自然、逼真的体验。正如现实生活中,我们习惯于通过语言和表情来传达思想和情感,然而,在虚拟世界中,人机交互需要以更加直观、生动的方式进行操作、控制和交互。 为了更好地满足市场的…

Elasticsearch:评估 RAG - 指标之旅

作者:Quentin Herreros,Thomas Veasey,Thanos Papaoikonomou 2020年,Meta发表了一篇题为 “知识密集型NLP任务的检索增强生成” 的论文。 本文介绍了一种通过利用外部数据库将语言模型 (LLM) 知识扩展到初始训练数据之外的方法。 …

如何使用Access中的窗体与数据打交道,看这篇文章就够了

Access数据库由一个或多个包含相关信息的表组成。一旦创建了这样一个空数据库,就可以遍历所有的表来填充信息。 然而,这可能会变得乏味和混乱。当你试图输入数据时,很难遵循表中数据之间的关系。访问输入窗体是一个很有价值的工具。你可以设计输入窗体,以便以逻辑格式输入…

python读取所有sheet内容到另一个文件中

实现效果: 将原excel中的步骤、预期效果列按回车拆成多行数据,其余字段值填充其他数据 实现结果: # This is a sample Python script.# Press ShiftF10 to execute it or replace it with your code. # Press Double Shift to search everyw…

单目相机测距(3米范围内)二维码实现方案(python代码 仅仅依赖opencv)

总体思路:先通过opencv 识别二维码的的四个像素角位置,然后把二维码的物理位置设置为 cv::Point3f(-HALF_LENGTH, -HALF_LENGTH, 0), //tl cv::Point3f(HALF_LENGTH, -HALF_LENGTH, 0), //tr cv::Point3f(HALF_LENGTH, HALF_LENGTH, 0), //br cv::P…

我有才满足于自媒体行业的知识付费平台课程

用户管理 提供会员特权和积分奖励,提高用户忠诚度和购买力。 用户通过在平台上进行消费、签到、参与活动等方式获取积分,用于兑换丰厚奖品或提升会员等级。增强用户的参与感与忠诚度,提高用户粘性,并刺激用户的购买力。 为用户打…

3.镜像加速器

目录 1 阿里云 2 网易云 从网络上拉取镜像的时候使用默认的源可能会慢,用国内的源会快一些 1 阿里云 访问 阿里云-计算,为了无法计算的价值 然后登录,登录后搜索 容器镜像服务 点击容器镜像服务 点击管理控制台 点击 镜像工具->镜像…

vue3 vue-cropper@next 实现图片裁切功能

Vue Cropper 实现上传图片预览&#xff0c;裁切上传效果 下载 pnpm add vue-croppernext使用 <template><inputref"inputRef"class"hidden"accept".png,.jpeg,.jpg"multipletype"file"change"handleUploadChange&quo…

基于ssm实现的工资管理系统

一、系统架构 前端&#xff1a;jsp | jquery | layui 后端&#xff1a;spring | springmvc | mybatis 环境&#xff1a;jdk1.8 | mysql | maven 二、代码及截图 三、功能介绍 01. 登录页 02. 首页 03. 用户管理-基本资料 04. 用户管理-修改密码 05. 人事管理-部门列表…

Leetcode—409.最长回文串【简单】

2023每日刷题&#xff08;四十八&#xff09; Leetcode—409.最长回文串 强烈吐槽&#xff01;&#xff01;&#xff01; 非常不理解&#xff0c;同样的代码&#xff0c;为什么C跑不了C就跑得了&#xff0c;力扣编译器是对C语言有歧视吗&#xff1f;&#xff1f;&#xff1f;…

【springboot原理篇】Bean的加载方式,面试必看

&#x1f308;键盘敲烂&#xff0c;年薪30万&#x1f308; 目录 一、上古时代原始方式&#xff1a; &#x1f4d5;XML文件 ~~bean定义 &#x1f440;演示获取bean&#xff1a; ❌缺点&#xff1a; &#x1f4d5;注解方式&#xff1a; ~~component ~~指定扫描路径&#…

如何使用 Oracle SQL Developer 连接 pgvector

如何使用 Oracle SQL Developer 连接 pgvector 1. 下载 postgresql 的 jdbc 驱动2. Oracle SQL Developer 配置第三方驱动3. Oracle SQL Developer 配置 postgres 连接 1. 下载 postgresql 的 jdbc 驱动 访问 https://jdbc.postgresql.org/download/&#xff0c;下载驱动&…