计算机网络——详解TCP三握四挥

文章目录

  • 前言
  • 一、三次握手
    • 1.1 三次握手流程
    • 1.2 tcp为什么需要三次握手建立连接?
  • 二、四次挥手
    • 2.1 四次挥手流程
    • 2.2 为什么是四次,不是三次?
    • 2.3 为什么要等待2msl?
    • 2.4 TCP的保活计时器

前言

TCPUDP是计算机网络结构中运输层的两个协议。

  • 传输控制协议 TCP(Transmission Control Protocol):提供面向连接的,可靠的数据传输服务(它通过三次握手建立连接,通过四次挥手终止连接)。
  • 用户数据协议 UDP(User Datagram Protocol):提供无连接的,尽最大努力的数据传输服务(不保证数据传输的可靠性)。
  • 序列号(Sequence Number):TCP报文段中的一个字段,用于标识数据流中的每个字节,确保数据的有序传输。
    确认号(Acknowledgment Number):TCP报文段中的一个字段,用于确认接收方已成功接收到的数据,并指示发送方可以继续发送后续数据。
    SYN标志(Synchronize Sequence Numbers):同步序列号标志,用于建立连接时同步双方的初始序列号。
    ACK标志:确认标志,用于确认接收到的数据。
    FIN标志:结束标志,用于终止连接时表示不再发送数据。

一、三次握手

1.1 三次握手流程

如图:
三次握手

第一次握手

  • 客户端发送SYN报文:客户端向服务器发送一个带有SYN标志的TCP报文段,报文中包含客户端选择的初始序列号seq=x(序列号是随机的),TCP规定,SYN报文请求不能携带数据,但需要消耗一个序列号。此时客户端进入SYN_SENT状态。
  • 作用:客户端向服务器表明自己希望建立连接,并告知服务器自己的初始序列号,以便后续数据传输时进行同步。

第二次握手

  • 服务器响应SYN+ACK报文:服务器收到客户端的SYN报文后,TCP服务器收到请求报文后,如果同意连接,则向客户端发送一个带有SYNACK标志的报文段。报文中包含服务器选择的初始序列号seq=y,以及对客户端序列号的确认号ack=x+1。这个报文也不能携带数据,但是同样要消耗一个序号。此时服务器进入SYN_RCVD状态。
  • 作用:服务器向客户端确认已收到其连接请求,并告知客户端自己的初始序列号,同时确认客户端的序列号,确保双方的序列号同步。

第三次握手

  • 客户端发送ACK报文:客户端收到服务器的SYN+ACK报文后,向服务器发送一个带有ACK标志的报文段,报文中包含对服务器序列号的确认号ack=y+1,TCP规定,ACK报文段可以携带数据,但是如果不携带数据的话则不消耗序号。此时客户端和服务器都进入ESTABLISHED状态,连接建立成功。
  • 作用:客户端确认已收到服务器的SYN报文,并确认服务器的序列号,确保双方的序列号完全同步。

连接正式建立,双方可以开始数据传输。

1.2 tcp为什么需要三次握手建立连接?

三次握手的原因

  • 三次握手才可以阻止重复历史连接的初始化(主要原因)
  • 三次握手才可以同步双方的初始序列号
  • 三次握手才可以避免资源浪费

原因一:避免历史连接

简单来说,三次握手的首要原因是为了防止旧的重复连接初始化造成混乱

我们考虑一个场景,客户端先发送了 SYN(seq = 90)报文,然后客户端宕机了,而且这个 SYN 报文还被网络阻塞了,服务器端并没有收到,接着客户端重启后,又重新向服务端建立连接,发送了 SYN(seq = 100)报文(注意!不是重传 SYN,重传的 SYN 的序列号是一样的)。

看看三次握手是如何阻止历史连接的:
在这里插入图片描述

客户端连续发送多次 SYN(都是同一个四元组)建立连接的报文,在网络拥堵情况下:

  • 一个旧 SYN 报文最新的 SYN报文早到达了服务端,那么此时服务端就会回一个 SYN + ACK 报文给客户端,此报文中的确认号是 91(90+1)
  • 客户端收到后,发现自己期望收到的确认号应该是 100 + 1,而不是 90 + 1,于是就会回 RST 报文。
  • 服务端收到 RST 报文后,就会释放连接。
  • 后续最新的 SYN 抵达了服务端后,客户端与服务端就可以正常的完成三次握手了。

上述中的旧 SYN 报文称为历史连接,TCP 使用三次握手建立连接的最主要原因就是防止历史连接初始化了连接。

如果是两次握手连接,就无法阻止历史连接,那为什么 TCP 两次握手无法阻止历史连接呢?

主要是因为在两次握手的情况下,服务端没有中间状态给客户端来阻止历史连接,导致服务端可能建立一个历史连接,造成资源浪费

在两次握手的情况下,服务端在收到 SYN 报文后,就进入 ESTABLISHED 状态,意味着这时可以给对方发送数据,但是客户端此时还没有进入 ESTABLISHED 状态,假设这次是历史连接,客户端判断到此次连接为历史连接,那么就会回 RST 报文来断开连接,而服务端在第一次握手的时候就进入 ESTABLISHED 状态,所以它可以发送数据的,但是它并不知道这个是历史连接,它只有在收到 RST 报文后,才会断开连接。
在这里插入图片描述
可以看到,如果采用两次握手建立 TCP 连接的场景下,服务端在向客户端发送数据前,并没有阻止掉历史连接,导致服务端建立了一个历史连接,又白白发送了数据,妥妥地浪费了服务端的资源。

因此,要解决这种现象,最好就是在服务端发送数据前,也就是建立连接之前,要阻止掉历史连接,这样就不会造成资源浪费,而要实现这个功能,就需要三次握手

所以,TCP 使用三次握手建立连接的最主要原因是防止历史连接初始化了连接。

原因二:同步双方初始序列号

TCP 协议的通信双方, 都必须维护一个序列号, 序列号是可靠传输的一个关键因素,它的作用:

  • 接收方可以去除重复的数据;
  • 接收方可以根据数据包的序列号按序接收;
  • 可以标识发送出去的数据包中, 哪些是已经被对方收到的(通过 ACK 报文中的序列号知道);

可见,序列号在 TCP 连接中占据着非常重要的作用,所以当客户端发送携带初始序列号SYN 报文的时候,需要服务端回一个 ACK 应答报文,表示客户端的 SYN 报文已被服务端成功接收,那当服务端发送初始序列号给客户端的时候,依然也要得到客户端的应答回应,这样一来一回,才能确保双方的初始序列号能被可靠的同步。
在这里插入图片描述

四次握手其实也能够可靠的同步双方的初始化序号,但由于第二步和第三步可以优化成一步,所以就成了三次握手。

而两次握手只保证了一方的初始序列号能被对方成功接收,没办法保证双方的初始序列号都能被确认接收。

原因三:避免资源浪费

如果只有两次握手,当客户端发生的 SYN 报文在网络中阻塞,客户端没有接收到 ACK 报文,就会重新发送 SYN由于没有第三次握手,服务端不清楚客户端是否收到了自己回复的 ACK 报文,所以服务端每收到一个 SYN 就只能先主动建立一个连接,这会造成什么情况呢?

如果客户端发送的 SYN 报文在网络中阻塞了,重复发送多次 SYN 报文,那么服务端在收到请求后就会建立多个冗余的无效链接,造成不必要的资源浪费。
在这里插入图片描述

即两次握手造成消息滞留的情况下,服务端重复接受无用的连接请求 SYN 报文,而造成重复分配资源。

二、四次挥手

2.1 四次挥手流程

如图:
在这里插入图片描述
第一次挥手

  • 客户端发送FIN报文:客户端向服务器发送一个带有FIN标志的TCP报文段,表示客户端已经没有数据要发送了,但仍然可以接收数据。报文中包含一个序列号seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时客户端进入FIN_WAIT_1状态。TCP规定,FIN报文段即使不携带数据,也要消耗一个序列号。
  • 作用:客户端主动关闭连接,通知服务器自己已经完成数据发送,等待服务器的确认。

第二次挥手

  • 服务器响应ACK报文:服务器收到客户端的FIN报文后,向客户端发送一个带有ACK标志的报文段,确认号为ack=u+1,并且带上自己的序列号seq=v。此时服务器进入CLOSE_WAIT状态,TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。
    客户端收到该报文后进入FIN_WAIT_2状态。
  • 作用:服务器确认已收到客户端的FIN报文,但此时服务器可能还有数据需要发送,因此不会立即关闭连接。

第三次挥手

  • 服务器发送FIN报文:当服务器完成数据发送后,向客户端发送FIN=1,ack=u+1报文,表示服务器也没有数据要发送了。报文中还包含一个序列号seq=w,此时服务器进入LAST_ACK状态。
  • 作用:服务器通知客户端自己已经完成数据发送,等待客户端的最终确认。

第四次挥手

  • 客户端响应ACK报文:客户端收到服务器的释放连接的FIN报文后,向服务器发送确认报文ACK=1,确认号为ack=w+1,自己的序列号是seq=u+1此时客户端进入TIME_WAIT状态,服务器收到该报文后进入CLOSED状态。
  • 作用:客户端确认已收到服务器的FIN报文,连接正式关闭。客户端进入TIME_WAIT状态,等待一段时间(2MSL)后,确保服务器已收到最终的ACK报文,然后进入CLOSED状态。

2.2 为什么是四次,不是三次?

tcp是全双工通信,服务端和客服端都能发送和接收数据。
tcp在断开连接时,需要服务端和客服端都确定对方将不再发送数据。

  • 第1次挥手:由客户端向服务端发起,服务端收到信息后就能确定客户端已经停止发送数据。
  • 第2次挥手:由服务端向客户端发起,客户端收到消息后就能确定服务端已经知道客户端不会再发送数据。
  • 第3次握手:由服务端向客户端发起,客户端收到消息后就能确定服务端已经停止发送数据。
  • 第4次挥手:由客户端向服务端发起,服务端收到信息后就能确定客户端已经知道服务端不会再发送数据。

为什么不是3次挥手?

在客服端第1次挥手时,服务端可能还在发送数据,所以第2次挥手和第3次挥手不能合并。

2.3 为什么要等待2msl?

为什么需要等待

  1. 为了保证客户端发送的最后一个 ACK 报文段能够到达服务端。 这个 ACK 报文段有可能丢失,因而使处在 LAST-ACK 状态的服务端就收不到对已发送的 FIN + ACK 报文段的确认。服务端会超时重传这个 FIN+ACK 报文段,而客户端就能在 2MSL 时间内(超时 + 1MSL 传输)收到这个重传的 FIN+ACK 报文段。接着客户端重传一次确认,重新启动 2MSL 计时器。最后,客户端和服务器都正常进入到 CLOSED 状态。

  2. 防止已失效的连接请求报文段出现在本连接中。客户端在发送完最后一个 ACK 报文段后,再经过时间 2MSL,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样就可以使下一个连接中不会出现这种旧的连接请求报文段。

为什么等待的时间是 2MSL

MSLMaximum Segment Lifetime报⽂最⼤⽣存时间,它是任何报⽂在⽹络上存在的最⻓时间,超过这个时间报⽂将被丢弃。

TIME_WAIT 等待 2 倍的 MSL,⽐较合理的解释是:⽹络中可能存在来⾃发送⽅的数据包,当这些发送⽅的数据包被接收⽅处理后⼜会向对⽅发送响应,所以⼀来⼀回需要等待 2 倍的时间。
在这里插入图片描述

⽐如如果被动关闭⽅没有收到断开连接的最后的 ACK 报⽂,就会触发超时重发 FIN 报⽂,另⼀⽅接收到 FIN 后,会重发 ACK 给被动关闭⽅, ⼀来⼀去正好 2 个 MSL

2.4 TCP的保活计时器

除时间等待计时器外,TCP 还有一个保活计时器(keepalive timer)。

设想这样的场景:客户已主动与服务器建立了 TCP 连接。但后来客户端的主机突然发生故障。显然,服务器以后就不能再收到客户端发来的数据。因此,应当有措施使服务器不要再白白等待下去。这就需要使用保活计时器了。

服务器每收到一次客户端的数据,就重新设置保活计时器,时间的设置通常是两个小时。若两个小时都没有收到客户端的数据,服务端就发送一个探测报文段,以后则每隔 75 秒钟发送一次。若连续发送 10 个探测报文段后仍然无客户端的响应,服务端就认为客户端出了故障,接着就关闭这个连接。
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【AD】3-6 层次原理图

自上而下 1.放置-页面符号,并设置属性 2.放置-端口 可通过如下设置将自动生成关掉 3.放置-添加图纸入口,并创建图纸 自下而上 1.子图的原理图页设计 设计资原理图,复制网络标签,智能粘贴未PORT 2.新建主图原理图 创建框…

C语言【指针篇】(四)

前言:正文1. 字符指针变量2. 数组指针变量2.1 数组指针变量是什么?2.2 数组指针变量怎么初始化 3. 二维数组传参的本质4. 函数指针变量4.1 函数指针变量的创建4.2 函数指针变量的使用4.3 两段有趣的代码4.3.1 typedef关键字 5. 函数指针数组6. 转移表 总结 前言&am…

认识苹果SWIFT语言

Swift 是苹果公司于 2014 年在 WWDC(苹果全球开发者大会)上发布的一种编程语言,旨在替代 Objective-C,用于开发 iOS、macOS、watchOS 和 tvOS 等苹果平台的应用程序。Swift 的设计目标是结合 C 和 Objective-C 的优点,…

python集合set的常用方法

目录 集合的定义 集合的基础操作 多个集合之间的操作 集合的for循环 集合的定义 集合的基础操作 集合.add(元素) 添加新元素 集合.pop() 从集合中随机取出一个元素 集合.clear() 清空集合 集合.remove(元素) 移除元素 #定义集合,集合自动去重了 set1{"春"…

2019年01月全国POI数据分享(同源历史POI分享系列)

2019年01月全国范围POI数据 2019年01月份全国范围历史POI数据,全国范围所有类别共59336781个POI 2019年01月全国范围POI数据按大类统计 大类代码大类名称2019年01月该类POI数量010000汽车服务1151164020000汽车销售213647030000汽车维修517367040000摩托车服务1800…

简单介绍JVM

1.什么是JVM? JVM就是Java虚拟机【Java Virtual Machine】,简称JVM。主要部分包括类加载子系统,运行时数据区,执行引擎,本地方法库等,接下来我们一一介绍 2.类加载子系统 JVM中运行的就是我们日常写的JA…

关于流水线的理解

还是不太理解,我之前一直以为,对axis总线,每一级的寄存器就像fifo一样,一级一级的分级存储最后一级需要的数据。 像这张图,一开始是在解析axis流形式的数据包,数据包一直都能输入,所以valid一直…

基于PHP和MySQL的用户登录注册系统实现

系统架构 系统采用前后端分离的架构,使用PHP作为后端语言,MySQL作为数据库。以下是系统的整体架构图: 这个架构图展示了系统的三个主要层次: 前端界面层:包含用户交互的三个页面(注册、登录和欢迎页面&am…

【湖北省计算机信息系统集成协会主办,多高校支持 | ACM出版,EI检索,往届已见刊检索】第二届边缘计算与并行、分布式计算国际学术会议(ECPDC 2025)

第二届边缘计算与并行、分布式计算国际学术会议(ECPDC 2025)将于2025年4月11日至13日在中国武汉盛大召开。本次会议旨在为边缘计算、并行计算及分布式计算领域的研究人员、学者和行业专家提供一个高水平的学术交流平台。 随着物联网、云计算和大数据技术…

从零开始用react + tailwindcss + express + mongodb实现一个聊天程序(七) 主题设置

1. 引入daisyUi 我们用的是^4.12.23版本 daisyUI介绍 Install daisyUI as a Tailwind CSS plugin — Tailwind CSS Components ( version 4 update is here ) 切换主题功能我们仿照daisyUI themes — Tailwind CSS Components ( version 5 update is here ) 1.在tailwind.co…

EGO-Planner的无人机视觉选择(yolov5和yolov8)

EGO-Planner的无人机视觉选择(yolov5和yolov8) 效果 yolov5检测效果 yolov8检测效果 一、YOLOv8 vs YOLOv5:关键差异解析 1. 训练效率:为何YOLOv8更快? 架构轻量化 YOLOv8采用C2f模块(Cross Stage Partia…

.net8 使用 license 证书授权案例解析

创建 webapi 项目 使用 .NET CLI 创建一个 ASP.NET Core Web API 应用,并添加指定的 NuGet 包,可以按照以下步骤操作: 创建 ASP.NET Core Web API 项目: dotnet new webapi -n WebAppLicense cd WebAppLicense添加 Standard.Li…

uniapp中使用leaferui使用Canvas绘制复杂异形表格的实现方法

需求: 如下图,要实现左图的样式,先实现框架,文字到时候 往里填就行了,原来的解决方案是想用css,html来实现,发现实现起来蛮麻烦的。我也没找到合适的实现方法,最后换使用canvas来实现&#xff…

支付宝 IoT 设备入门宝典(下)设备经营篇

上篇介绍了支付宝 IoT 设备管理,但除了这些基础功能外,商户还可以利用设备进行一些运营动作,让设备更好的帮助自己,本篇就会以设备经营为中心,介绍常见的设备相关能力和问题解决方案。如果对上篇感兴趣,可以…

Vue学习教程-18Vue单文件组件

文章目录 前言一、单文件组件的构成二、组件引用三、组件的应用举例1.组件实例2.显示结果 前言 Vue 单文件组件(又名 *.vue 文件,缩写为 SFC)是一种特殊的文件格式,它允许将 Vue 组件的模板、逻辑 与 样式封装在单个文件中。组件…

games101 作业5

题目 光线追踪的核心算法: 1.光线的生成 2.光线与三角的相交 题解 1.光线的生成 如课件中的图所示: image plane 就是 代码中的scene的FrameBuffer。 但是,FrameBuffer 是窗口坐标系中,而光线是世界坐标系中的。所以我们需要将scene中的屏…

正交投影与内积空间:机器学习的几何基础

前言 本文隶属于专栏《机器学习数学通关指南》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢! 本专栏目录结构和参考文献请见《机器学习数学通关指南》 正文 🔍 1. 内积空间的…

Cherry Studio + 火山引擎 构建个人AI智能知识库

🍉在信息化时代,个人知识库的构建对于提高工作效率、知识管理和信息提取尤为重要。尤其是当这些知识库能结合人工智能来智能化地整理、分类和管理数据时,效果更为显著。我最近尝试通过 Cherry Studio 和 火山引擎 来搭建个人智能知识库&#…

深入浅出数据结构(图)

图 图的逻辑结构定义逻辑结构基本术语(提起来脑海有印象就行)对比 存储结构(邻接矩阵和邻接表)铺垫 邻接矩阵透过问题看本质无向图相关有向图相关网图相关 伪代码实现类(无向图)构造函数(伪代码…

Android Activity启动流程详解

目录 Activity 启动流程详细解析 1. 应用层发起启动请求 1.1 调用 startActivity() 1.2 通过 Instrumentation 转发请求 2. 系统服务处理(AMS 阶段) 2.1 Binder IPC 通信 2.2 AMS 处理流程 2.3 跨进程回调 ApplicationThread 3. 目标进程初始化…