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

JavaEE: 深入探索TCP网络编程的奇妙世界(二)

文章目录

  • TCP核心机制
    • TCP核心机制二: 超时重传
      • 为啥会丢包?
      • TCP如何对抗丢包?
      • 超时重传的时间设定
        • 超时时间该如何确定?


TCP核心机制

前一篇文章 JavaEE: 深入探索TCP网络编程的奇妙世界(一)
书接上文~

TCP核心机制二: 超时重传

在网络传输中,并不会一帆风顺,而是可能出现"丢包情况"~

为啥会丢包?

产生丢包的原因有很多种

  1. 数据传输的过程中,发生了bit翻转,收到这个数据的接收方/中间的路由器啥的,发现计算校验和对不上了

    发现错误,要及时止损,不能将错就错!
    于是就把这个数据包丢弃掉了,不再继续往后转发/不交给应用层使用.

  2. 数据传输到某个节点(路由器/交换机),这个节点,负载太高了.

    某个路由器,单位时间只能转发N个包,由于现在是网络高峰期,这个路由器单位时间需要转发的包超过N了(发不过来了),那么后续传输过来的数据就可能被这个路由器直接丢弃掉.

TCP如何对抗丢包?

由于丢包这件事情,是完全随机的,是不可预测的.

TCP再怎么厉害,也不可能避免数据发生丢包!

TCP能做的就是,感知到数据是否丢包,如果丢包,就重新再发一次.

假设网络丢包率是10%(数据报到达对方是90%)
10%的丢包是相当高的数字,出现这个情况,都是网络发生严重故障(LOL就卡成ppt了),此时可以赶紧找运营商保修了~我在这里只是举个例子~
此时,进行一次重传,两次传输至少一次到达对方的概率: 1 - 10% * 10% = 99%
传输次数越多,数据到达对方的概率就越大.

关于是否丢包,这个问题需要通过应答报文来区分

  • 收到应答报文,说明数据没丢包
  • 没收到应答报文,就说明数据丢包了

我们都知道,数据在网络传输过程中是需要消耗时间的.

那么我们来思考一下这个问题: "没有收到应答报文"表明暂时没收到,那么是过一会就收到了,还是永远都收不到??

其实,发送方发送数据之后,会给出一个"时间限制"(超时时间).
如果在这个时间限制之内,没有收到反馈的ack,那么就视为是数据丢包了.

丢包这个过程有两种情况:

  • 一是主机A发送数据给B之后,可能因为网络拥堵等原因,导致数据无法达到主机B.
    在这里插入图片描述
  • 二是A发送的数据到达B了,但是A在一个特定的时间间隔内没有收到B发来的确认应答(ACK丢失),于是就会重新发送.
    在这里插入图片描述

情况一还好说,A重新发一份就是了.

但是情况二就有点麻烦了,因为A又重新发送了一份相同的数据,接收到多份相同数据感觉好像没啥大不了的,但是万一你传输的数据是"扣款"这样的请求呢?

为了解决情况二引发的问题,TCP会对上述情况做处理.

接收方有一个接收缓冲区,收到的数据先进入到缓冲区里,等后续再收到数据,就会根据序号,在缓冲区中,找对应的位置(排序),如果发现,当前序号1-1000这个数据,已经在缓冲区中存在了,那么就会直接把新收到的这个1-1000数据包丢弃掉~

其实就是去重,通过去重来确保应用程序,调用read读出来的数据,是唯一的,不重复的~

超时重传的时间设定

这里的时间,不是固定值,而是动态变化的.

发送方第一次重传,超时时间是 t1 ,如果重传之后,仍然没有ack,还会继续重传,此时的超时时间就变成了 t2.
t2 > t1
每多重传一次,超时时间的间隔就会变大 / 重传的频次会降低.

经过一次重传之后,就能让数据到达对方的概率提高很多,再重传一次,又会提升很多.

反之,如果重传几次,都没有顺利到达,这就说明网络的丢包率已经到达了一个非常高的程度,网络发生了严重故障,大概率没法继续使用了.

此时再重传的快,也没意义,不如省点力气~

当然了,重传也不会无休止的进行,当重传达到一定的次数之后,TCP不会尝试重传,就认为这个连接已经G了.
TCP会先尝试进行"重置/复位 连接",发送一个特殊的数据包"复位报文".

  • 如果网络这会恢复了,复位报文就会重新连接,使通信可以继续进行.
  • 如果网络还是有严重问题,复位报文也没有得到回应,此时TCP就会单方面放弃连接.

    之前讲过,连接就是通信双方各自保存对方的信息.
    发送方释放掉信息之前保存的接收方的相关信息,那么这个连接也就没了.

针对上述内容,我们只关注策略,不关注参数.因为参数可以根据需要进行修改,而策略是固定的~

超时时间该如何确定?
  • 最理想的状态下,只要找到一个最小的时间,来保证"确认应答一定能在这个时间内返回"就OK.
  • 但是这个时间长短,是会随着网络环境的不同,而发生改变.
  • 如果超时时间设的太长,那么就会影响整体的重传效率
  • 如果超时时间设的太短,那么就有可能会频繁发送重复的包

TCP为了保证无论在任何环境下都能比较高性能的通信,因此会动态计算这个最大超时时间.

  • Linux中(BSD Unix和Windows也是如此),超时以500ms为一个单位进行控制,每次判定超时重发的超时时间都是500ms的整数倍
  • 如果重发一次之后,仍然得不到应答,那么将等待2*500ms后进行重传
  • 如果仍然得不到应答,那么将等待4*500ms进行重传.以此类推,以指数形式递增.
  • 等累积到一定的重传次数,TCP就会认为网络或者对端主机出现异常,就会强制关闭连接.

确认应答,和超时重传,相互补充,共同构建了TCP"可靠传输机制"~

下一篇文章JavaEE: 深入探索TCP网络编程的奇妙世界(三)

本文到这里就结束啦~

在这里插入图片描述

相关文章:

  • 建立队列,插入队列,删除队列
  • scrapy之setting文件详解
  • 0基础学习PyTorch——时尚分类(Fashion MNIST)训练和推理
  • 阿里云函数计算 x NVIDIA 加速企业 AI 应用落地
  • 10.Lab Nine —— file system-上
  • 丹摩智算(damodel)部署stable diffusion实验
  • 三子棋小游戏
  • 【React】组件通信
  • Android 已经过时的方法用什么新方法替代?
  • 使用Python解决数据分析中的相关性分析
  • macOS 15 Blank OVF - macOS Sequoia 虚拟化解决方案
  • 分享个锂电池升压芯片,3.7V升5V大电流输出的芯片。AD2403 PWM升压芯片
  • 如何创建一个包含多个列的表?
  • 828华为云征文|华为云Flexus云服务器X实例——部署EduSoho网校系统、二次开发对接华为云视频点播实现CDN加速播放
  • fastadmin本地安装插件提示”请从官网渠道下载插件压缩包(code:2)(code:1)“
  • es6
  • express如何解决request entity too large问题
  • Javascript设计模式学习之Observer(观察者)模式
  • macOS 中 shell 创建文件夹及文件并 VS Code 打开
  • PHP 程序员也能做的 Java 开发 30分钟使用 netty 轻松打造一个高性能 websocket 服务...
  • Redash本地开发环境搭建
  • Redis 中的布隆过滤器
  • tensorflow学习笔记3——MNIST应用篇
  • Terraform入门 - 3. 变更基础设施
  • V4L2视频输入框架概述
  • vue:响应原理
  • vue从创建到完整的饿了么(11)组件的使用(svg图标及watch的简单使用)
  • Vue学习第二天
  • 阿里云购买磁盘后挂载
  • 不上全站https的网站你们就等着被恶心死吧
  • 工作踩坑系列——https访问遇到“已阻止载入混合活动内容”
  • 讲清楚之javascript作用域
  • 老板让我十分钟上手nx-admin
  • 深度学习入门:10门免费线上课程推荐
  • 使用Maven插件构建SpringBoot项目,生成Docker镜像push到DockerHub上
  • 微信开源mars源码分析1—上层samples分析
  • 温故知新之javascript面向对象
  • 异常机制详解
  • 原生js练习题---第五课
  • 找一份好的前端工作,起点很重要
  • 智能合约Solidity教程-事件和日志(一)
  • 深度学习之轻量级神经网络在TWS蓝牙音频处理器上的部署
  • Python 之网络式编程
  • 移动端高清、多屏适配方案
  • ​LeetCode解法汇总2583. 二叉树中的第 K 大层和
  • # 深度解析 Socket 与 WebSocket:原理、区别与应用
  • $GOPATH/go.mod exists but should not goland
  • (23)Linux的软硬连接
  • (70min)字节暑假实习二面(已挂)
  • (C语言)字符分类函数
  • (pojstep1.1.1)poj 1298(直叙式模拟)
  • (第8天)保姆级 PL/SQL Developer 安装与配置
  • (二)【Jmeter】专栏实战项目靶场drupal部署
  • (分布式缓存)Redis分片集群
  • (附源码)springboot“微印象”在线打印预约系统 毕业设计 061642