网络原理(二)TCP的可靠传输
网络原理(一)目录
- 网络原理
- 应用层
- 传输层
- 先说UDP(不可靠传输)
- 重点说明TCP(可靠传输)
- 一、确认应答
- 二、超时重传
- 三、链接管理
- 建立连接
- 断开链接
- 四、滑动窗口
- 五、流量控制(也是保证可靠性的机制)
- 六、阻塞控制
- 七、延迟应答(效率机制)
- 八、捎带应答(效率机制)
- 九、面向字节流(粘包问题)
- 十、异常情况(心跳包)
网络原理
网络协议的在实际运用是分为5层协议及:
- 应用层
- 传输层
- 网络层
- 数据链路层
- 物理层
这五层结构在,java 网络编程中已经有所现,具体用法具体实现的功能,都有。
应用层
这里主要的一个协议也是目前网络上最常用的一个协议,HTTP协议。
这层结构,决定数据要传输什么,拿到数据后如何使用。HTTP为什么是最长用的一个应用层协议,其本质就是在确定框架后,程序员可以在自定义一些协议,可控性和操控大大提升。
及约定数据报的数据格式,就是在自定义协议。
而如何约定?
- 确定要传输那些信息(根据需求走)
- 确定数据按照啥样的格式来组织。
-
网络上传输的,本质都是二进制字符串,就需要将上述的穿输的信息整合为一个字符串。但是在传输内容的时候,一个我们需要的数据,其实和其他数据是合在一起的。我们要如何拿到所需要的数据。很简单,我们在传输数据的时候,设定一个符号,或者距离单位。锁定所需要的数据。
-
比如我规定,属性之间用 ’,‘ 隔开 ,每个对象用 ‘\n’ 隔开,结束标志用 ’;‘ 隔开 。
-
只要发送方发送数据按照这个格式传输,然后接收方,在解析数据的时候,用这个格式解析就好;
-
在开发中,有一些特定的现成的格式。可以直接拿来使用。比如之前的一种典型的格式,xml ,还有现在用的比较多的一种格式。json,
什么是json。
{
userId:100
userPos:10-100
}
使用{}作为标识,{}里面的诺干个键值对,每个键值对用 ’,‘ ,分割,键值对,用 ’:‘ 分割。 键必须是字符串,值就可以是一个object。
传输层
先说UDP(不可靠传输)
这个就是UDP 的报文格式。


- 端口是2个字节,所以端口可以取:0-- > 65535
- 报文长度就局限了正文最大能装多少的内容。64KB。所以如果用UDP进行传输一个很长的数据,就需要包一个较大的数据,拆成很多分,用UDP传输。(很复杂)
所以用UDP传输数据,不能太大,否则就会出现问题。 - 校验和,是为了校验数据的准确的。在真实的网络传输中就会遇到很多问题。磁场,太阳风暴,等等。这些都会干扰数据的稳定。而校验和就是用来判定,当前的数据是否出错。(通常是设定一种特殊的算法,比如取正文中的一些字符,然后算出一个数据,然后传输完毕后在验证一次)
重点说明TCP(可靠传输)
TCP如何实现可靠传输?
一、确认应答
什么是确认应答呢?其实就很简单,比如网上购物,商家发货,货物根据你的信息发送货物,然后送到哪里并且,你确认了收货,然后平台就会将钱给商家,这就是一个很简单的应答模式。

这个模型有一个问题,就是网络的状况有很多种,会出现后发先至的问题。对应到上述的例子就是,遇到强降雨,但是后边的货车走了另一条路。走的就比之前的车要快。
异常状态

正常状态

如何解决这个问题?
此时就需要对消息进行编号。
- 给发送的消息分配一个需要
- 同时应答报文,给出一个确认顺序

协议格式:

TCP将每个字节的数据都进行了编号,基序列号。

- 源/目的端口号:表示数据是从哪个进程来,到哪个进程去;
- 32位序号/32位确认号:后面详细讲;
- 4位TCP报头长度:表示该TCP头部有多少个32位bit(有多少个4字节);所以TCP头部最大长度是15 * 4 = 60
- 6位标志位:
- URG:紧急指针是否有效
- ACK:确认号是否有效
- PSH:提示接收端应用程序立刻从TCP缓冲区把数据读走
- RST:对方要求重新建立连接;我们把携带RST标识的称为复位报文段
- SYN:请求建立连接;我们把携带SYN标识的称为同步报文段
- FIN:通知对方,本端要关闭了,我们称携带FIN标识的为结束报文段
- 16位窗口大小:后面再说
- 16位校验和:发送端填充,CRC校验。接收端校验不通过,则认为数据有问题。此处的检验和不光
- 包含TCP首部,也包含TCP数据部分。
- 16位紧急指针:标识哪部分数据是紧急数据;
- 40字节头部选项:暂时忽略;

首先接送方的序号和发送方的序号无关
确认序号 1001 的含义。
- 小于1001的数据,我已经收到
- 我接下来想要发送方从1001开始的数据
在之前说过,网络传输的时候,会有后发先至的情况,同样的这个也是。但是能,TCP在传输时会有序号,序号天然就有顺序,所以对于这种情况,只要在接收方接收前排序就好了。(优先级队列就能完成这个)、
对于TCP来说,自身也承担了这个整队的任务,TCP会有一个缓冲区(内核中的一个区域),每个socket都有自己的缓冲区。然后TCP就可以按照序号针对收到的消息进行针对。
如果一切顺利就可以应答了。可问题就是,现实并不顺利。比如丢包。
二、超时重传
那么什么是丢包呢?
传输数据的时候要经过各个节点,可是问题来了,一台机器节点的转发能力是有极限的,也就是说到达极限的机器,就可能会引起丢包的问题。(实时性的APP或者应用对于丢包的问题非常的敏感),如果丢包了接收方就收不到了。自然就不会返回ACK。
如何解决?
之前的逻辑,就是发送方发送消息会受到一个接收者的反馈的接收信息。但是丢包了,数据就不完整了。在队列里之前排好序的数据,因为丢包使得,序列并不完整。
此时因为序列并不完整,就不会交给接收者。然后序列就会等待,如果此时的序列等待时间长了,发送方迟迟拿不到应答。那么发送方就知道,传输出了问题,那么就会重新再发一次。直到拿到应答。(这个就叫超时重传)
有一个细节:
- 数据直接丢失,接收方没收到,自然不会发 ack
- 接收方接收到数据了,但是返回的ack 却丢了。
此时发送方分不清这些情况,只能重传。
可是此时,接收方已经在缓冲区中有了数据,再传一个,就重复了。此时接收方的缓冲区,会根据数据的序列,自动去重。保证应用程序中读到的数据任然只有一份
如果多次重复发送还没有收到ack 那么多半网络出了问题。主要是假设丢包率为10%,那么连续两次丢包,概率就是10% * 10%=1%
而以上这两种机制就是,TCP的可靠性保障。及:
- 确认应答
- 超时重传
三、链接管理
TCP创建链接:三次握手
TCP断开链接:四次挥手
建立连接
什么是三次握手?
握手是指通信双方,进行一次网络交互。相当于客户端和服务器之间,通过三次交互,建立连接关系(双方各自记录了对方的信息)

互相应答,确保双方的网络是完整的。并建立连接(有那么一滴滴可靠性的说法,但并不是)
等建立连接完毕,服务器 accept 把建立好的链接从内核拿到应用程序中。

- 此时如果ACK 为 1 ,则表示当前的TCP数据报为一个应答报文
- 此时如果SYN为 1 ,则表示当前的TCP数据报为一个同步报文
- 如果ACK和SYN都是 1 ,则这个报文就是 SYN + ACK
做这么多。其实就是验证自己的发送能力和接收能力是否正常。
断开链接
什么是四次挥手?
通信的双方,各自给对方发一个FIN(结束报文),在各自给对方放回ACK

建立连接,一定是客户端发起,但是断开链接客户端和服务器都有可能。(并且通常ACK与FIN并不能重合)(FIN比特位位1的时候)
注意:
三次握手:ack与syn是同一个时机触发的(都是由内核完成)
四次握手:ack与fin内是不同时机出发的。前者由内核完成,而后者需要程序中 socke t的 close 方法才会触发fin、

四、滑动窗口
是为了解决,数据传输的效率问题。
对每一个发送的数据段,都要给一个ACK确认应答。收到ACK后再发送下一个数据段。这样做有一个比较大的缺点,就是性能较差。尤其是数据往返的时间较长的时候。
可靠性的提升,往往代表,效率的损失。

可以看到,客户端A这边传输5000个字节,要应答四次。此时A就用了大量的时间去等待ACK
既然这样一发一收的方式性能较低,那么我们一次发送多条数据,就可以大大的提高性能(其实是将多个段的等待时间重叠在一起了)

此时将数据进行批量发送。统一发送后,一起等待ACK的返回。这个批量传输的过程就是滑动窗口
等待的传输数据到达一定的数量,而这个批量等待的数据称为————》窗口大小

白色区域,相当于等待的窗口~~
批量发送了四个数据,就等待四个ACK。
这个批量发送也会出现问题。
比如:
- 数据包以抵达,而ACK却丢了

这种情况,即使丢了这么多的ack,对于可靠性也没有任何影响。
确认序号的意思是指,该序号之前的数据都已经收到了,后一个 ACK 能表示前面的 ACK。(覆盖了)
- 数据包就直接丢了

解释:由于刚才1001 - 2000 这个数据丢了,所以接收方任然要索要1001,不会说因为收到的是2001-3000,就返回3001。接下来几次的数据 ack ,确认序号都是1001, B 再次向 A 反复索要 1001 这个数据,A这边识别到多个 1001 的请求,就知道 1001-2000丢了。于是 A 就重传了 1001-2000 这个数据。
当 A 1001-2000 这个数据重传后,B 收到了就会 传一个7001这个ACK,因为,数据只是缺了1001-2000这一段,补上之后,不用传关于这个段的 ACK,根据滑动窗口特点,后一个 ACK 就能表示他前面的数据已经到达 B。也就是,虽然1001-2000这一段没收到,但是其他的还在收啊。只是没有应答。补上了之后就开始应答。
这个重传的过程也叫:快速重传。
五、流量控制(也是保证可靠性的机制)
按道理来说,窗口越大,意味着,批量传输数据越多,也就意味着整体速度越快。但是数据多,就不意味着安全可靠。
数据一次性发的多,而快,一下子就把接收缓冲区给充满了。如果继续发送数据,此时就会丢包。这个时候,就需要控制一下流量

当ACK为1的时候,窗口大小字段就会生效。这里16位窗口是建议。
重要:发送方的窗口大小 = 流量控制 + 拥塞控制

如此就达成了阻塞的效果。
六、阻塞控制
滑动窗口大小 = 流量控制 + 拥塞控制
流量控制:平衡了接收方的处理能力
阻塞控制:衡量了传输路劲的处理能力
在java网络编程的哪一章中网络的传输是需要经过很多个节点的。如果任何一个设备,处理能力达到瓶颈,都会对整体的传输塑料产生明显影响。
而阻塞控制,就需要找到,衡量中间节点,传输的能力。怎么找?通过一次次实验,找到一个合适的发送速率
- 开始的时候,按照一个小的速率发送
- 如果不丢包,就可以扩大窗口的大小
- 如果丢包,就可以缩小窗口的大小

慢开始:刚开始传输会给一个非常小的窗口
指数规律增长:每一次扩大窗口,是翻倍成长。快速接近网络传输路径的能力瓶颈。
传输轮次:第一次发送,第二次发送。。。。
拥塞避免,“加法增大” :指数增长懂啊一定的阈值,就变成线性增长。避免一次性增加很多突然超出上限。
网络拥塞:增长到一定程度,出现丢包,认为当前的窗口大小,已经是传输的极限了。
七、延迟应答(效率机制)
TCP 可靠性的核心,是确认应答,ACK要发,但是不是立即发,而是稍微磨蹭一会再发,TCP中决定传输效率的关键元素就是,窗口大小。

此时服务器并不会立即返回一个ACK,也不一定要等到服务器将缓冲区里的数据全部拿出来,等待一下,然后偷偷的拿数据,悄悄的消耗缓冲区的数据,这样就相当于增大了窗口的大小。然后等到合适的时机服务器在返回ACK应答。
这样使得窗口大小似乎变大了,然后效率相应的变大了。
但是也并不是所有的报都延迟。
- 数量限制:每隔N个包就应答一次;
- 时间限制:超过最大延迟时间就应答一次;
八、捎带应答(效率机制)
是基于延迟应答的。
适用于:客户端,服务器,之间的通信模型,通常是“一问一答”这用模式
通信模型:
- 一问一答:绝大部分服务器都是这样
- 多问一答:上传大文件
- 一问多答:下载大文件
- 多问多答:游戏串流
原则是,客户端发送一个消息,需要等待服务器的ACK,但是因为延迟等待,数据实际上已经上传了,并且也处理好了,按照一般逻辑就是,将处理好的数据,返回给客户端,之前 ACK 还没有返回给客户端,那么此时 ACK 就会捎带着服务器处理好的数据返回给客户端。(原本分两次的返回,现在一次就可以)
九、面向字节流(粘包问题)
这个有一个巨大的问题,就是粘包问题。
根据上面的说法综合一下就知道,我们发送方传输的数据,是多个数据放在一起传输的。然后在缓冲区上集结排列,然后接收方如何将数据分离,读出一个完整的数据报,此时造成的结果就是,容易读出半个包,或者一个半的包,反正就是不是我们想要的。
如何解决?
提前约定好,数据的格式。比如:
- 约定结尾符号,接收方收到后,通过结尾符号知道一个完整的数据。
- 约定长度,约定数据的前几个字节,表示整个数据包的长度,通过光标读取字节长度。读取完整数据。
十、异常情况(心跳包)
- 进程关闭 / 进程崩溃
- 进程没有了,socket是文件,随之关闭,虽然进程没有了,但是连接还在,仍然可以继续关闭连接(四次挥手)
- 主机关机
- 先杀死所有的用户进程,也会触发四次挥手,如果没有挥完,比如 对方发了一个fin,咱们没来得及 ack 就关机了,姿势对端,就会重传fin ,重传几次后,发现没有 ACK ,尝试重置连接,如果还不行,就直接释放链接。
- 主机掉电
主机瞬间关闭,来不及任何挥手操作。
- 对方是发送方 :接收方收不到ACK =》超时重传 =》重置链接 =》释放链接
- 对方是接收方:发送方,没办法立即知道,接收方死机了,这边还没有来得及发新数据,就没了。
- TCP为了防止这种情况,内置了一个机制,心跳机制(周期性的,如果没有心跳,就代表挂了),也就是接收方会给发送方定期发一个心跳包(ping),然后发送方会给接收方发送一个返回(pong)
- 如果每个ping都有一个pong返回,就说明接收方是好的。如果bing了很多次,还没反应,就知道就收方挂了。
- 网线断开
- 同上,与主机掉电原理一样
相关文章:
网络原理(二)TCP的可靠传输
网络原理(一)目录 网络原理应用层传输层先说UDP(不可靠传输)重点说明TCP(可靠传输)一、确认应答二、超时重传三、链接管理建立连接断开链接 四、滑动窗口五、流量控制&am…...
Chat GPT 使用教学,文字创作、学习
目录 文章长篇文章学习任何东西文章 大纲、目录、标题、内容 写出10个即将被AI取代的工作的文章标题 当然,以下是一些可能会被AI取代的工作的文章标题:"未来十年,AI将如何改变传统制造业的就业格局?" "智能客服崛起:人工智能如何重塑客户服务行业?"…...
Android之 Canvas绘制
一 Canvas介绍 1.1 Canvas 是绘制图形的重要类之一,它可以在 View 或 SurfaceView 上绘制各种图形和文本. 1.2 要创建 Canvas,首先需要有一个 View 或 SurfaceView 对象,在 View 或 SurfaceView 的绘制方法中,可以通过 Canvas 的…...
Vue + Element UI 前端篇(十五):嵌套外部网页
Vue Element UI 实现权限管理系统 前端篇(十五):嵌套外部网页 嵌套外部网页 在有些时候,我们需要在我们的内容栏主区域显示外部网页。如查看服务端提供的SQL监控页面,接口文档页面等。 这个时候就要求我们的导航菜…...
Jabbi的Rust学习日记(二)
特征: 就目前我学习到的rust知识来看,我认为rust有以下几个特征: 链式调用表达式强类型 use 使用use导入包,我觉得rust的导包和python的很像 main main函数是rust可执行程序最先执行的代码,可以说是程序的入口&…...
【杂】环形时钟配色笔记
配色网站笔记 coolorsflatuicolorscolordrophttps://www.webdesignrankings.com/resources/lolcolors/ 配色2...
会话跟踪技术学习笔记(Cookie+Session)+ HTTP学习笔记
一、核心知识点(重点): 1.1 Cookie 1. Cookie:是一种客户端会话技术,数据会被保存在客户端,Cookie会携带数据访问服务器,用以完成一次会话内多次请求间的数据共享 2. 过程:浏览器…...
分类预测 | MATLAB实现PCA-BiLSTM(主成分双向长短期记忆神经网络)分类预测
分类预测 | MATLAB实现PCA-BiLSTM(主成分双向长短期记忆神经网络)分类预测 目录 分类预测 | MATLAB实现PCA-BiLSTM(主成分双向长短期记忆神经网络)分类预测预测效果基本介绍程序设计参考资料致谢 预测效果 基本介绍 分类预测 | MATLAB实现PCA-BiLSTM(主成分双向长短期记忆神经网…...
Yarn 和 npm 的区别
Yarn 和 npm 都是 JavaScript 的包管理工具,它们的主要区别在于以下几个方面: 性能:Yarn 的安装速度和包的下载速度通常比 npm 更快,这是因为 Yarn 使用本地缓存和并行下载等技术来提高性能。 可靠性:Yarn 具有更好的…...
第20章 原子操作实验(iTOP-RK3568开发板驱动开发指南 )
在上一章节的实验中,对并发与竞争进行了实验,两个app应用程序之间对共享资源的竞争访问引起了数据传输错误,而在Linux内核中,提供了四种处理并发与竞争的常见方法,分别是原子操作、自旋锁、信号量、互斥体,…...
Android 开机自启动
APP需要开机自启动,要通过开机广播实现。 1,在AndroidManifest.xml中增加权限 <!-- .接收启动完成的广播权限 --><uses-permission android:name"android.permission.RECEIVE_BOOT_COMPLETED" /> 2,在AndroidManifes…...
01_前端css编写的三种方式
前言 CSS的引入方式共有三种:行内样式、内部样式表、外部样式表 一、内联式引入 用法: 在元素上直接通过style属性进行设置css样式设置 示例: <h1 style"color:red;">style属性的应用</h1> <p style"font-si…...
07-垃圾收集算法详解
上一篇:06-JVM对象内存回收机制深度剖析 1.分代收集理论 当前虚拟机的垃圾收集都采用分代收集算法,这种算法没有什么新的思想,只是根据对象存活周期的不同将内存分为几块。一般将java堆分为新生代和老年代,这样我们就可以根据各…...
Redis高并发分布式锁实战
高并发场景秒杀抢购超卖bug实战重现 秒杀抢购场景下实战JVM级别锁与分布式锁 大厂分布式锁Resisson框架实战 Lua脚本语言快速入门与使用注意事项 Redisson分布式锁源码剖析 Redis主从架构锁失效问题解析 从CAP角度剖析Redis与Zookeeper分布式锁区别 Redlock分布式锁原理与…...
MybatisPlus分页插件使用
一. 效果展示 二. 代码编写 2.1 pom <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.2</version> </dependency>2.2 添加配置类 Configuration MapperScan(…...
Linux指令二【进程,权限,文件】
进程是一个具有一定独立功能的程序在一个数据集上的一次动态执行的过程,是操作系统进行 资源分配和调度的一个独立单位,是应用程序运行的载体。 一、进程基本指令 1.ps:当前的用户进程 ps 只显示隶属于自己的进程状态ps -aux 显示所有进程…...
uni-app运行到微信开发者工具-没有打印的情况
前言 到我们进场使用微信开发者工具时,就会发现它经常会有bug,特别是在软件更新,组件库更新之后 最近在更新微信开发者工具之后发现所有打印都不显示了,虽然是小问题-但对于强迫症很烦 以为是代码配置问题-结果是更新之后打印开…...
由前端接口入门学习后端的controller层
由前端接口入门学习后端的controller层 一、简单介绍一下controller层:二、前端调用后端接口时,一般会传递参数给后端,后端的控制层是如何接收的呢?三、更深入地介绍一下关于请求体参数DTO作为入参Map作为入参 本文是以一个前端工…...
HJ71 字符串通配符
Powered by:NEFU AB-IN Link 文章目录 HJ71 字符串通配符题意思路代码 HJ71 字符串通配符 题意 问题描述:在计算机中,通配符一种特殊语法,广泛应用于文件搜索、数据库、正则表达式等领域。现要求各位实现字符串通配符的算法。 要求ÿ…...
ffmpeg 开发笔记
参考: FFmpeg音视频处理 - 知乎 通过python实时生成音视频数据并通过ffmpeg推送和混流 - 知乎 直播常用 FFmpeg & ffplay 命令 - 知乎 音视频 FFMPEG 滤镜使用 - 知乎 官网: ffmpeg Documentation...
【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...
c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
day36-多路IO复用
一、基本概念 (服务器多客户端模型) 定义:单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用:应用程序通常需要处理来自多条事件流中的事件,比如我现在用的电脑,需要同时处理键盘鼠标…...
作为测试我们应该关注redis哪些方面
1、功能测试 数据结构操作:验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化:测试aof和aof持久化机制,确保数据在开启后正确恢复。 事务:检查事务的原子性和回滚机制。 发布订阅:确保消息正确传递。 2、性…...
【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案
目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后,迭代器会失效,因为顺序迭代器在内存中是连续存储的,元素删除后,后续元素会前移。 但一些场景中,我们又需要在执行删除操作…...
6️⃣Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙
Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙 一、前言:离区块链还有多远? 区块链听起来可能遥不可及,似乎是只有密码学专家和资深工程师才能涉足的领域。但事实上,构建一个区块链的核心并不复杂,尤其当你已经掌握了一门系统编程语言,比如 Go。 要真正理解区…...
篇章二 论坛系统——系统设计
目录 2.系统设计 2.1 技术选型 2.2 设计数据库结构 2.2.1 数据库实体 1. 数据库设计 1.1 数据库名: forum db 1.2 表的设计 1.3 编写SQL 2.系统设计 2.1 技术选型 2.2 设计数据库结构 2.2.1 数据库实体 通过需求分析获得概念类并结合业务实现过程中的技术需要&#x…...
从零开始了解数据采集(二十八)——制造业数字孪生
近年来,我国的工业领域正经历一场前所未有的数字化变革,从“双碳目标”到工业互联网平台的推广,国家政策和市场需求共同推动了制造业的升级。在这场变革中,数字孪生技术成为备受关注的关键工具,它不仅让企业“看见”设…...
