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

【网络原理】❤️Tcp 常用机制❤️ —— 延时应答,捎带应答, 面向字节流, 异常情况处理。保姆式详解 , 建议收藏 !!!

本篇会加入个人的所谓鱼式疯言

❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言

而是理解过并总结出来通俗易懂的大白话,

小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的.

🤭🤭🤭可能说的不是那么严谨.但小编初心是能让更多人能接受我们这个概念 !!!

在这里插入图片描述

引言

想象一下,如果没有可靠的数据传输机制,我们的网络世界将会怎样?信息可能会丢失,邮件可能无法送达,在线交易可能无法完成。幸运的是,TCP协议为我们提供了一种确保数据完整性和顺序的通信方式。它不仅确保了数据的准确传输,还通过一系列核心机制优化了网络性能。

目录

  1. 延时应答

  2. 捎带应答

  3. 面向字节流

  4. 异常情况处理

一. 延时应答

1. 延时应答的初识

小伙伴应该知道,确认应答是返回一个 ACK = 1 , 且带有 确认序号没有载荷 的报文。

而延时应答则是在 确认应答流量控制 的基础上, 进行了 优化了

之前是一收到发送方发来的数据, 就立即 返回 ACK

但是延时应答的是: 等待一段时间 ,等 应用程序 消耗了 接收缓冲区 一定的数据之后, 再返回 ACK

2. 延时应答的大体流程

在这里插入图片描述

如上图:

上面是一个 接收缓冲区

假设这个缓冲区的空间为 100KB , 原有数据 40KB, 然后新发送(写) 缓冲区数据 20KB, 还剩下 40KB空间大小

如果说,按照 确认应答机制实施 , 接收方一收到这个 20KB数据ACK 就返回接收缓冲区剩余40KB数据的信息 , 这样的话,

从上一篇我们学习过的 流量控制的角度 , 我们知道滑动窗口的窗口大小就是根据接收缓冲区的剩余大小来衡量的, 如果接收缓存区 剩余空间越小, 发送方 设置的窗口就越小发送速度就越低, 效率就越低效

但是我们假设设置一个 100ms 的等待时间

让应用程序在这 100 ms 内尽可能的消耗 尽可能的消耗接收缓冲区 的数据, 可能 消耗了20KB

ACK 等待了100ms 后返回, 就会从之前返回剩余40KB 变成 返回60KB 的信息。

同时发送方就会调整为 更大的窗口大小 , 从而 加快传输速度

可能小伙伴们还听的不是很清楚吧

下面小编举个栗子说明一下吧

小编是在一所高校上学的, 可能平常又很懒,几乎不写作业~

然后老师也 看不下去 了,就发个消息提醒我。

老师: 同学, 你作业好多没写, 快把你作业补一补吧!

这时小编有两种策略:

策略一: 小编立即回复

我: 老师, 最近有点忙,抱歉哦, 我尽快把作业补完。

这时我就指不定什么时候能够补完了, 说是马上去补,肯定是去哈皮咯, 好比 确认应答机制

策略二: 小编先 不急着回复老师消息 , 而是先一顿 狂补八九次作业 , 最后只 剩下两次 , 然后我再去回复老师。

我: 老师, 我这个作业已经快写完了, 我只剩下两次作业了,分分钟搞定了。 就好比: 延时应答机制

这上面的两次策略就对应两种不同的应答, 确认应答机制延时应答机制

我们就可以看出, 我 立即补作业过会再写作业 的方案的效率是 不一样 的,过会写作业还 指不定什么时候开始补 呢, 但是现在开始补就相当于 延时一点时间 , 让我不断 消耗现有作业的量, 从中体现 延时应答机制 更能体现出 提高效率

鱼式疯言

总结补充:

  1. 延时应答其实本质上就是 多消耗接收缓冲区数据多加快传输速率提高效率减少Tcp因可靠传输而造成的性能的影响

如果要保证在延时应答的机制下, 缓冲区的数据是 尽可能被消耗而不是增加 的, 就要确保以下两点

  1. 应用程序 是不断 源源不断的消耗着缓冲区的数据的
  1. 发送方不会有 新的数据 发送过来 。

二. 捎带应答

1. 捎带应答的初识

捎带应答是什么?

捎带应答可以认为就是 在原本是 三次握手中中间一次的发送过程SYN ACK 同时合并 捎带一起发送 , 也是 一种提高效率减少Tcp可靠传输的对性能的损耗

鱼式疯言

捎带应答不用可以是 同一个源头发送的数据合并, 也可以是 不同的源头发送的数据合并


下面我们以四次挥手合并成三次挥手为栗子来说明:

2. 捎带应答的大体流程

在这里插入图片描述

在之前的文章中, 小编讲过 四次挥手 的全过程, 如果还有点模糊的小伙伴记得回顾哦 ❣️ ❣️ ❣️ ❣️

三次握手, 四次挥手详解

这次从四次挥手的中间两次来介绍捎带应答的大体流程

首先, 按照一般的情况来说, 中间两次挥手是不能合并的, ACK是系统内核返回到,只要一收到发送方发送FIN 就会立即返回 ACK, 而 FIN应用程序 发送的, 只要执行到 close() 才会发送。

从正常情况考虑, 两个报文的发送时间是 不同的 , 所以很难 同时一起发送

但是因为Tcp有 延时应答的机制,就可以让 快一点的ACK 经可能的 慢点发送, 直到应用程序执行到 close() 方法后 , ACK 就和 FIN 一起同时发送, 从而 提高效率 , 这就是 捎带应答机制

什么是捎带应答机制, 可能主编这边讲的还不是很通俗易懂, 下面来举个小栗子吧 ❣️ ❣️ ❣️ ❣️

比如我室友是特别懒的一位, 就在我旁边的床位, 平常要不是上课就根本不想动, 就整天躺在床上刷视频。

他经常看着看着就口渴了, 这时他因为太懒了, 根本不想动, 那么他就会等等…

等到什么时候呢?

等到他要上厕所了, 就会 下床先去上厕所 , 然后就 顺便去喝水

我室友的这种方式就完美的诠释了什么叫做 捎带应答 , 他等的过程就相当于 ACK 等待 FIN 相似直到 FIN 需要发送了 然后再 顺便发送ACK ,从而 提高传输的效率

鱼式疯言

总结补充

对于 相同的发送源头Tcp 可以直接实现使用 捎带应答

对于 不同的发送源头TCP 就需要在 延时应答 的基础上使用 捎带应答

三. 面向字节流

1. 黏包问题

在前面的文章中, 谈及Tcp 必然谈及Tcp 的特点之一——面向字节流

关于前面Tcp 面向字节流的特点还有不清楚的, 小伙伴们可以重新巩固下哦 ❤️ ❤️ ❤️ ❤️

面向字节流博客详解

而在本篇中就需要给小伙伴们介绍Tcp 在面向字节流进行网络通信时, 所可能产生的黏包问题

什么是黏包问题?

在这里插入图片描述

入上图:

就是当发送方发送几段数据后, 这些数据就会在接收缓冲区中连成一片, 相互黏合。

而当 主机B 从接收缓冲区中读取数据 , 就有可能会出现:

aa , abbb , ccc

aaab, bbc, cc

aa,abb,bccc 等… 各种读取情况, 就会出现实际数据信息读取错误, 这样的情况称之为: 黏包问题

如何解决黏包问题呢?

下面提供两种方案 🤔 🤔 🤔 🤔 🤔

2. 黏包问题的解决方案

<1>. 使用分隔符

使用分隔符 例如 \n 换行来 分隔每一个数据包 的信息。

比如当 主机A 写出一段数据, 就使用 nextLine() 方法, 只要 换行了就说明写出完毕

主机B 读入一段数据 , 就使用 println 来读取, 代表 一行一行的来读取

<2>. 使用固定长度来分隔

使用固定长度这个方案, 我们就可能参考UDP 的报头结构,

在这里插入图片描述

从载荷(应用层数据包)的首部开始分配一个 2/ 4字节 长度的空间, 用一段固定的空间来作为 每个数据包与数据包的边界 , 如此用一个 固定的长度来分隔数据 ,就很难出现 黏包问题

鱼式疯言

关于这种黏包问题, 小编这里只是举例 两种常用的方案 , 其实解决黏包问题的方案是 很多种的

四. 异常情况处理

对于异常情况的可能性很多, 下面小编就一一来为小伙伴们讲解 💞 💞 💞 💞

1. 进程崩溃

对于Java来说, 当进程崩溃时, 就会抛出异常, JVM 就会来处理 , 这时就会使 整个程序结束

但实际上, 操作系统就进行 善后工作 , 自动回收 PCB 的文件描述符表 , 并且会对 每一个PCB 中的 文件描述符表 的每一个 Socket 对象 进行释放。

针对 Socket文件 进行释放, 也就是进行 四次挥手断开连接操作。

2. 主机正常关机

对于主机正常关机,会出现两种情况:

1. 四次挥手 先完成 ,正常断开连接后, 主机正常关机

在这里插入图片描述

<2>. 四次挥手还没完成, 主机就已经断开连接

如上图 ,还没来得及完成四次挥手, 主机 A就先关机 , 此时主机B 没有收到ACK

而且 不能感知到主机A 已经关机了, 所以主机B 就会 一直进行超时重传 , 当主机B 超时重传一定次数后,就 不会进行超时重传 , 主机B 就会 自动一方断开连接 , 也就是 删除对方的信息

3. 主机意外掉电

对于主机意外掉电的情况, 就有分为

  1. 发送方先发完数据掉电

  2. 接收方接收完就掉电

<1>. 发送方掉电

在这里插入图片描述

当A 发送了两段报文后, A 就直接掉电, 掉电之后B返回两个ACK

但从B 的角度来看, 不知道 A掉电了 还是 休息一会再发

所以这时B 就会发送一个 探测报文 , 来 检查A 是嘎了 还是 想歇会

如果B 接收到A 返回的ACK 就说明, A 想休息会。

如果发送了多次探测报文都 没有接收到了ACK , 就说明 A已经嘎了

这时B 就会 单方面释放连接

鱼式疯言

补充说明

探测报文是一种 不携带载荷, 为了 触发ACK 的一种 特殊报文

就是用来探测对方 生死 的一种数据包, 该数据包我们称之为 心跳包

心跳包是一种为了 触发ACK 而周期性发送的一种探测报文 , 在Tcp配置中, 探测报文的周期是 秒/ 分钟来衡量的。

应用程序 则这一层会 自动生成 一些心跳包 , 来达到更快的 保活机制

<2>. 接收方断电

在这里插入图片描述

如果 A 发送多段数据包 , 没有接收到 ACK , 就会超时重传, 但 重传达到一定的上限, A 就会重置连接, 如果 重置连接失败 , A 就会单方面的释放连接

4. 网线断开

在这里插入图片描述

如果网线断开了, 也就意味着网络通信瘫痪了, 那么 A 无法发送数据给B , 同时 B也无法接收到 A 发送过来的数据

A 的角度来看, A 发送数据后, 没有接收到ACK , 就会超时重传 , 超时重传达到 一定的上限 那么就会 重置连接 , 那么 A 这边就会单方面的释放连接

B 的角度来看, B未接收到数据, 就会 周期性的发送心跳包 , 如果发送 一定次数的心跳包都没有接收到 ACK , 同时也会但 方面释放连接

鱼式疯言

总结补充 :

发送方 的探测方式: 重置连接

接收方 的探测方式: 心跳包

总结

  • 延时应答: Tcp用于减少 可靠传输 带来的损耗的一种机制, 消耗一定时间尽可能的 消耗接收缓冲区中已有的数据,
    提高效率。

  • 捎带应答: 将两次或两次以上的发送 合并成一次一起发送 ,提高效率, 并可能会利用 延时应答机制 来配合使用。

  • 面向字节流:面向字节流的常见问题就是 粘包问题 , 常用的解决方案: 使用 分隔符 和 固定数据长度

  • 异常情况处理:介绍多次异常的情况, 同时 重置连接 或者 心跳包 确定是否存活, 如果对端不存活就会 单方面的释放连接

如果觉得小编写的还不错的咱可支持 三连 下 (定有回访哦) , 不妥当的咱请评论区 指正

希望我的文章能给各位宝子们带来哪怕一点点的收获就是 小编创作 的最大 动力 💖 💖 💖

在这里插入图片描述


http://www.kler.cn/a/307874.html

相关文章:

  • Spring——事务
  • 408笔记合集
  • HTTP常见的状态码有哪些,都代表什么意思
  • 【大数据测试HBase数据库 — 详细教程(含实例与监控调优)】
  • AutoCad 无界面开发
  • 软件工程概论项目(二),node.js的配置,npm的使用与vue的安装
  • Kafka支持SSL/TLS协议技术深度解析
  • Android13 下载apk并安装apk
  • 跳出大厂圈子——普通程序员如何开启逆袭之路
  • mac上什么压缩软件没有广告,苹果电脑解压软件BetterZip有广告吗
  • 深入理解MATLAB中的事件处理机制
  • ROS组合导航笔记:融合传感器数据
  • 嵌入式数据库sqlite和rocksdb的介绍以及对比
  • 分治算法归并排序
  • CSP-J/S赛前知识点大全2:初赛纯靠记忆的知识点
  • Docker高级管理之compose容器编排与私有仓库的部署
  • FPGA实现串口升级及MultiBoot(四)MultiBoot简介
  • [苍穹外卖]-12Apache POI入门与实战
  • 滚雪球学SpringCloud[2.1]:服务注册中心Eureka
  • robomimic基础教程(三)——自带算法
  • 【Linux】ICMP
  • 【开端】docker基线漏洞修复
  • React-Hooks-Form 集成 Zod 校验库
  • go get -u @latest没有更新依赖模块
  • 如何通过深度学习实践来理解深度学习的核心概念
  • Ubuntu 24.04中安装virtualenv