[网络]TCP/IP协议 之 TCP协议的核心机制(2)

文章目录

  • TCP核心机制
    • 1. 确认应答
    • 2. 超时重传
    • 3. 连接管理
      • 三次握手
      • 四次挥手
    • 4. 滑动窗口
    • 5. 流量控制
    • 6. 拥塞控制
    • 7. 延时应答
    • 8. 捎带应答
    • 9. 粘包问题
    • 10. 异常情况

TCP核心机制

1. 确认应答

(上篇)

2. 超时重传

(上篇)

3. 连接管理

建立连接的流程: 三次握手
断开连接的流程: 四次挥手

握手和挥手, 是打招呼的过程, 此时两个主机并没有进行实质上的数据交互, 只是为了建立连接或断开连接而打招呼

三次握手

建立连接, 就是通信双方, 各自保存对端的信息
据图完成上述过程, 需要经过三次网络交互
在这里插入图片描述
第一次: 三次握手的第一次, 一定是客户端先发起的
SYN数据报, 是标志位中的第五位

SYN, synchronize, 同步, 在TCP中, 同步 则是希望 服务器和客户端之间, 达成某种配合的关系, 达成某种有关联得状态
这个数据报, 不携带任何业务数据, 载荷部分是空的, 只有TCP报头
第二次: 服务器收到SYN, 需要返回ACK
然后还要给客户端发送SYN
这两次交互ACK 和 SYN 可以合并成一次网络通信, 将第二位和第五位标志位设为1即可
这么做的目的实际上是为了提高效率
第三次: 客户端收到SYN, 返回ACK

三次握手的意义:
1) 三次握手, 相当于"投石问路", 在证书传输业务数据之前, 先确认一下通信链路是否畅通
也相当于是TCP可靠传输的一种保证(辅助机制)
2) 通过三次握手, 来确认通信双方, 发送能力和接收能力都是正常的
举例:
在这里插入图片描述
此时, 只有通过三次交流, 才能完全确认发送方和接收方各自的发送能力和接收能力
3) 三次握手, 还需要协商一些必要的参数, 例如数据的开始序号
序号往往不是从 0 / 1 开始的, 而是三次握手的时候, 通信双方协商出一个数字
考虑一下场景:
在这里插入图片描述
第一次建立连接, 我们称"前朝", 第二次建立连接. 称"本朝"
如果前朝, 某个数据报, 在网络通信的过程中, 迷路了, 走了一个非常远的路线(没有丢包)
等待这个数据报饶了半天终于到达服务器的时候, 之前的连接已经断开了, 现在是新的连接了
那么服务器如何判断这个数据报是前朝还是当朝的呢?
就是根据序号来区分了
每次建立连接, 都是从一个新的数字, 作为起始序号的
当前本朝的数据, 序号一定是沿着我们其实序号往下的数字, 不会相差很多
如果收到一个数据报, 序号和其实序号差别很大, 就可以任务是前朝的数据报了, 此时就可以直接丢弃了

连接状态:
在这里插入图片描述
掌握两个即可:
listen: 是服务器出现的状态, 当服务器绑定端口成功之后, 机会进入到listen状态
established: 建立完成, 可以随时进行后续通信了

四次挥手

四次挥手, 客户端和服务器都可以主动发起断开连接
在这里插入图片描述
第一次: 发送方发送FIN 结束报文
FIN finish 结束报文, 标志位中的最后一位
在这里插入图片描述
第二次: 接收方收到FIN, 立刻返回ACK
第三次: 接收方的应用程序代码中, 调用close的时候, 才会触发FIN报文
意味着, 当收到发送方的FIN结束报文时, 返回ACK 和 发送FIN 并不是同一时刻发生的,
可能过了好久才执行close, 所以第二次和第三次挥手, 在正常情况下, 是不能合并的
但是, 在特殊情况下, 两次挥手可以合并
在TCP中, 有一个机制"延时应答", 回复ACK不是马上回复, 这个情况下, 就可以合并
第四次: A收到FIN, 返回ACK
只有当双方都收到了ACK, 连接才会断开, 双方才会删除对方的信息, 上述挥手过程只是在通知对方

状态:
在这里插入图片描述
CLOSE_WAIT: 被动一方的状态, 在接收FIN报文后, 等待代码调用close
代码中调用close越及时, 这里的状态就越不容易看到
如果有的时候, 在服务器看到大量的CLOSE_WAIT, 说明大概率代码忘记调用close了
TIME_WAIT: 主动一方的状态, 存在的意义, 就是为了应对最后一个ACK丢包这样的场景
在这里插入图片描述

主动方在收到被动方返回的FIN后, 不能立即释放TCP连接, 如果立即释放, 后续一旦对端重传了FIN, 此时, 主动方就无法应对了, 无法返回ACK了
但是, TINE_WAIT状态不是持续的, 而是有一定时间的, 在一定时间内, 如果没有收到重传的FIN,
意思就是最后一个ACK对方已经收到了, 此时TIME_WAIT就可以释放了
TIME_WAIT等待的时间, 一般是2MSL

MSL 理论上, 表示网络中两个结点之间传输数据的最大时间, 这个数值通常是1min
那么TIME_WAIT意味着2min后, 没有收到重传FIN, 就直接释放

4. 滑动窗口

滑动窗口, 是提高效率的一种机制
不引入滑动窗口:
在这里插入图片描述数据传输过程, A收到一个ACK, 才会发送下一个数据, 比较低效
引入滑动窗口:
在这里插入图片描述

从一条一条发送, 到批量发送, 把等待时间重叠了, 可以提高效率
不等待ACK, 批量发送多少数据, 这个数据量就表示窗口大小, 上图的窗⼝⼤⼩就是4000个字节(四个段).

在这里插入图片描述
发送前四个段的时候, 不需要等待任何ACK, 直接发送;
收到第⼀个ACK后, 滑动窗⼝向后移动, 继续发送第五个段的数据; 依次类推

滑动窗口, 如果出现丢包怎么办?
情况一: 数据报已经抵达, ACK丢了
在这里插入图片描述
此时不需要做任何处理
1001的ACK丢包, 但是后面的2001的ACK并没有丢包, 此时主机B已经接收到了1-2000的字节数据, 那么返回的ACK就包含了前面的效果
同理, 5001返回的ACK, 也包含了前面的效果
情况二: 数据包丢了
在这里插入图片描述
1001-2000的数据包丢了, 接收方按理来说应该按顺序接收字节数据, 此时他没有收到1001-2000的数据, 那么接下来不管发送什么数据, 都返回下一个应该是1001的ACK
那么, 当A连续收到若干个这样的ACK就会明白, 1001-2000这个数据包丢了, 所以就重新发送
当B收到这个数据包, 就会结合之前收到的所有数据包, 索要下一个数据包
在这里插入图片描述
当某处存在缺口时, 返回的ACK, 确认序号都是在索要这个缺口的数据
一旦缺口补充上, 接下来就可以从队列中最后一个数据的序号继续往后索要

上述这个, 在滑动窗口下, 搭配的丢包重传处理机制, 称为"快速重传"

如果TCP传输的数据比较少, 不频繁, 此时就不会触发滑动窗口, 这时仍然按照超时重传的方式解决丢包问题 如果TCP短时间传输大量的数据, 此时才会触发滑动窗口, 按照快速重传的方式解决丢包问题

滑动窗口虽能够提升效率, 但速度是不可能比UDP这种没有可靠机制的协议更快的

5. 流量控制

滑动窗口机制, 窗口大小是可变的, 可以通过窗口大小, 来控制发送方的发送速度
窗口越大, 发送数据越快, 但可能接收方处理不过来, 发生丢包
窗口越小, 发送速度越慢
那么此时, 最合理的做法, 就是接收方根据自身能力, 反向制约发送发的速度, 是双方达到一种平衡, 这样的机制, 就叫"流量控制"
在这里插入图片描述
接收方, 有一个接收缓冲区, 以未使用的空间大小作为发送方发送的窗口大小
在返回ACK的时候, 在TCP报文中有一个字段, 表示上述空闲空间大小

在这里插入图片描述
16位窗口大小, 这个字段只在ACK报文中生效, 含义就是接收方接收缓冲区的空闲空间的大小
16位, 能够表示64KB, 如果此时空闲空间大于64KB, 那么在选项中, 包含了一种特殊属性"窗口扩展因子"
最终的空闲空间大小为: 窗口大小 <<(左移) 窗口扩展因子
如果此时窗口大小为64KB, 窗口扩展因子为2, 那么实际上的空闲空间是64KB<<2, 相当于*4 = 256KB
发送方就可以根据这个来控制窗口大小
在这里插入图片描述

6. 拥塞控制

拥塞控制, 也是控制窗口大小的
上述的流量控制, 我们只考虑了接收方, 但是网络通信, 是要经过很多的交换机/路由器的, 中间的设备, 我们也不能忽视
那么我们可以根据实验的方式, 找到一个合适的窗口大小
刚开始按照小的窗口来发送数据, 如果没有出现丢包, 说明中间链路畅通, 就可以增加速度, 增加窗口大小
如果增加到一定程度, 出现丢包了, 此时发送方立即减小窗口大小, 继续发送看是否还会丢包
如果不丢包, 继续加
如果丢包, 继续减
这样就能找到一个合适的窗口大小完成运输了, 上述过程就称为"拥塞控制"

举例:

在这里插入图片描述
①刚开始, 以比较小的窗口来传输数据
②如果没有出现丢包, 按照指数方式扩大窗口
③指数增长过程中, 达到某个阈值, 就要变成线性增长
④增长到一定程度, 出现了丢包, 此时立刻把窗口变小
⑤缩小有两种方式:
1)直接缩到底, 回到最初慢启动 — 已经废弃
2)缩到出现丢包时窗口大小的一半 — 当前的方式

由于拥塞控制和流量控制都是控制窗口大小, 谁窗口小我们就听谁的!

7. 延时应答

延时应答, 本质上也是为了提高传输的效率
通过延时, 就可以使窗口大小得到提升, 从而提高效率
在这里插入图片描述
延长的时间, 有两种方式决定:
1)按照一定时间来延时
2)按照收到的数据量来延时
这两种策略是结合使用的

8. 捎带应答

建立在延时应答的基础上, 进一步提高效率
在这里插入图片描述
正常来说, ack是内核收到请求, 自动返回的
响应数据, 则是应用程序代码, 是执行了一系列逻辑之后, 返回的

由于延时应答, ack不一定会立即返回, 在ack等待的过程中, 正好要返回响应数据, 那么响应数据就会捎带着, 在TCP的报头中, 将确认序号/窗口大小都设置上, 就把两次传输合并成了一次传输, 这样的策略就叫"捎带应答"

9. 粘包问题

⾸先要明确, 粘包问题中的 “包” , 是指的应⽤层的数据包.
在TCP的协议头中, 没有如同UDP⼀样的 “报⽂⻓度” 这样的字段, 但是有⼀个序号这样的字段.
站在传输层的⻆度, TCP是⼀个⼀个报⽂过来的. 按照序号排好序放在缓冲区中.
站在应⽤层的⻆度, 看到的只是⼀串连续的字节数据.
那么应⽤程序看到了这么⼀连串的字节数据, 就不知道从哪个部分开始到哪个部分, 是⼀个完整的应
⽤层数据包
此时, 服务器就无法区分哪些是完整的应用层数据包
解决办法:
1)使用分隔符
2) 约定包的长度
思考: 对于UDP协议来说, 是否也存在 “粘包问题” 呢?
• 对于UDP, 如果还没有上层交付数据, UDP的报⽂⻓度仍然在. 同时, UDP是⼀个⼀个把数据交付给应
⽤层. 就有很明确的数据边界.
• 站在应⽤层的站在应⽤层的⻆度, 使⽤UDP的时候, 要么收到完整的UDP报⽂, 要么不收. 不会出
现"半个"的情况.

10. 异常情况

情况一: 其中一个进程崩溃了

强制杀死进程和进程崩溃, 其实是同样的效果, 操作系统, 都能够回收释放对应的PCB, 可以释放里面的文件描述符表, 就相当于调用close
此时, 仍然可以正常进行四次挥手, 并且能够挥完

情况二: 某个主机被关机(正常流程的关机)

对于正常流程的关机, 操作系统挥尝试强制介乎所有用户进程, 然后再进入关机流程
那么在结束进程之后, 也会进行四次挥手
但是可能在关机之间挥完了, 也可能没挥完
在这里插入图片描述

情况三: 某个主机电源掉电

如果A和B通信, A突然掉电了
此时A无法做出任何反应, 就关了
1)如果B是发送数据的一方:
B接下来发的数据, 都不会有ACK, B就会触发超时重传, 重传急促, 发送复位报文(RST), 也没有响应
此时B就单方面删除保存的A的信息
2)如果B是接收方
B再一定时间内没有收到A的数据, 就会触发心跳包
连续发送几个心跳包, A都没有回应, 这时B认为A挂了 于是单方面释放连接

心跳包, 只是一个没有载荷的数据包, 如果A正常, 就能回应ACK; 如果A挂了, B不会收到任何回应
TCP虽然内置了心跳包, 但是这个心跳包, 周期比较长, 指望通过这个心跳发现对端挂了, 往往需要分钟级别的时间, 在实际开发中, 经常会在应用层实现心跳包, 频率更高, 周期更短, 例如ping-pong

情况四: 网线断开

本质上就是第三种情况
比如A是发送方, B是接收方
A的角度, 就会触发超时重传, 触发RST, 单方面删除信息
B的角度, 就会触发心跳包, 对方无响应, 单方面删除信息

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

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

相关文章

相亲交友程序系统开发产品分析

相亲交友系统是一种专门为单身人士设计的社交平台&#xff0c;旨在帮助他们找到合适的伴侣。这类系统通常包括了线上和线下的多种互动方式&#xff0c;能够让参与者在舒适的环境中相识、相知。编辑&#xff1a;qawsed2466。以下是相亲交友系统的一些关键特点和优势&#xff1a;…

细数H.264 H.265 H.266区别

H.264、H.265&#xff08;HEVC&#xff09;和H.266&#xff08;VVC&#xff09;是三种不同的视频编码标准&#xff0c;它们在压缩效率、图像质量、支持的分辨率以及技术特性等方面存在显著差异。以下是对这三种编码标准的详细比较&#xff1a; 概述 H.264&#xff1a;也称为AV…

基于协同过滤算法+SpringBoot+Vue+MySQL的商品推荐系统

系统展示 用户前台界面 管理员后台界面 系统背景 当前的网络技术&#xff0c;软件技术等都具备成熟的理论基础&#xff0c;市场上也出现各种技术开发的软件&#xff0c;这些软件都被用于各个领域&#xff0c;包括生活和工作的领域。随着电脑和笔记本的广泛运用&#xff0c;以及…

基于Python的可视化在线学习系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于pythondjangovueMySQL的可…

QT操作数据库

思维导图&#xff1a; 学习内容&#xff1a; 1. QSqlDatabase:数据库管理类 主要完成数据库的创建、数据库的打开、关闭等操作 该类中常用函数&#xff1a; 1、 QSqlDatabase addDatabase(const QString &type, const QString &connectionName QLatin1String(default…

Science Robotics 在小动物模型中实现渐进和可逆主动脉收缩的软机器人平台

前言速览&#xff1a;目前对左心室压力过载引起心脏重构过程的理解主要来源于主动脉束带的动物模型。然而&#xff0c;这些研究未能同时控制疾病的进展和逆转&#xff0c;阻碍了其临床意义。为此&#xff0c;来自哈佛大学、麻省理工学院等的研究人员介绍了一种基于植入式可扩张…

@Transactional和@Synchronized的冲突

Transactional和Synchronized的冲突 场景 方法是先进行检查&#xff0c;然后新增&#xff0c;添加了事务注解&#xff0c;为了保证检查&#xff08;要求业务上唯一&#xff09;&#xff0c;添加了Synchronized注解 想法很简单&#xff0c;事务注解保证方法原子性&#xff0c…

git一个项目关联多个远程仓库

一行代码就行&#xff1a; git remote set-url origin [想要关联的远程仓库地址]想要关联哪个就切换哪个 或者不用每次切换&#xff0c;集中管理&#xff1a; Git->Manage Remotes 点击“”&#xff0c;填入Name和想要关联的远程库地址 每次push时执行命令 git push [为…

ssrf漏洞利用+CTF实例

引发ssrf漏洞的几个函数 file_get_contents() 把整个文件读入一个字符串中&#xff0c;获取本地或者远程文件内容fsockopen() 获得套接字信息curl_exec() 执行一个curl会话&#xff0c;由curl_init()初始化一个新的会话&#xff0c;返回一个curl句柄fopen() 打开文件或者URLre…

全国历年高考真题2008-2024

目录 分享链接&#xff1a; ⬇️⬇️⬇️ 点击下载

2024网络安全学习路线,最全保姆级教程,学完直接拿捏!

关键词&#xff1a; 网络安全入门、渗透测试学习、零基础学安全、网络安全学习路线 首先咱们聊聊&#xff0c;学习网络安全方向通常会有哪些问题 前排提示&#xff1a;文末有CSDN独家网络安全资料包&#xff01; 1、打基础时间太长 学基础花费很长时间&#xff0c;光语言都有…

基于微信小程序的高校实验室管理系统的设计与实现

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 基于微信小程序JavaSpringBootVueMySQL的高…

QT:音视频播放器

目录 一.播放器设计 二.需要使用的控件 三.选择视频 四.播放视频 五.暂停视频 六.关闭视频 七.播放状态设置 八.切换视频(上一首) 九.切换视频(下一首) 十.设置视频滑块 十一.更新滑块显示 十二.实现效果 十三.代码设计 1.mainwindow.h 2.mainwindow.cpp 一.播放…

并行程序设计基础——并行I/O(2)

目录 一、显式偏移的并行文件读写 1、阻塞方式 1.1 MPI_FILE_READ_AT 1.2 MPI_FILE_WRITE_AT 1.3 MPI_FILE_READ_AT_ALL 1.4 MPI_FILE_WRITE_AT_ALL 2、非阻塞方式 2.1 MPI_FILE_IREAD_AT 2.2 MPI_FILE_IWRITE_AT 3、两步非阻塞组调用 3.1 MPI_FILE_READ_AT_ALL_BEG…

基于SpringBoot的医院挂号预约管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于JavaSpringBootVueMySQL的医院挂号…

港科夜闻 | 叶玉如校长出席2024科技+新质生产力高峰论坛发表专题演讲,贡献国家科技强国战略...

关注并星标 每周阅读港科夜闻 建立新视野 开启新思维 1、叶玉如校长出席“2024科技新质生产力高峰论坛”&#xff0c;做了题为“三个创新&#xff1a;培育和发展新质生产力、贡献国家科技强国战略”的主题演讲。该论坛于9月2日在香港召开。论坛围绕夯实基础科研、推动源头创新、…

『功能项目』管理器基类【38】

我们打开上一篇37单例模式框架的项目&#xff0c; 本章要做的事情是编写管理器基类 首先创建脚本&#xff1a;ManagerBase.cs using UnityEngine; public abstract class ManagerBase : MonoBehaviour{public virtual void Init() { } } public class ManagerBase<T> : …

Docker容器技术1——docker基本操作

Docker容器技术 随着云计算和微服务架构的普及&#xff0c;容器技术成为了软件开发、测试和部署过程中的重要组成部分。其中&#xff0c;Docker作为容器技术的代表之一&#xff0c;以其简便易用的特点赢得了广大开发者的青睐。 Docker允许开发者在轻量级、可移植的容器中打包和…

JAVA——方法

public static 返回值类型 方法名(参数){//方法体return 数据; } 一、定义与调用 public class demo9_12 {public static void main(String[] args) {// 调用myName();}//定义public static void myName(){System.out.println("Hello World");} } 运行 二、含参数…

类和对象(c++)

欢迎来到本期频道&#xff01; 类和对象 类定义&#xff1a;格式&#xff1a;类域&#xff1a;访问限定符友元内部类this指针静态与非静态成员关系类型转换六大默认成员函数&#xff08;C98&#xff09;1️⃣构造函数2️⃣拷贝构造函数浅拷贝与深拷贝 3️⃣赋值重载拷贝函数4️…