【TCP 协议】报文格式,数据可靠传输的机制(一)

news2025/1/18 17:15:31

哈喽,大家好~我是你们的老朋友:保护小周ღ  


本期为大家带来的是网络编程的 TCP 传输控制协议的概念 ,首先会讲解 TCP 协议的报文格式,在学习报文格式之后,会学习两种 TCP 保证数据可靠传输的机制,确认应答,超时重传,这也是TCP 中较为核心的机制,以及接收缓冲区可以将数据排序,去重的功能。


本期收录于博主的专栏:JavaEE_保护小周ღ的博客-CSDN博客

适用于编程初学者,感兴趣的朋友们可以订阅,查看其它 “JavaEE基础知识”。
更多精彩敬请期待:保护小周ღ *★,°*:.☆( ̄▽ ̄)/$:*.°★* ‘


 一、网络编程简介

真实的网络通信是基于 TCP / IP 五层网络模型实现,协议分层,自上而下,应用层-> 传输层-> 网络层-> 数据链路层->物理层,协议分层管理,规定下层协议为上层协议提供服务(接口 - API),上层协议可以直接调用下层协议,但是不允许跨层调用。除应用层以外,其余几层都被操作系统封装好了,并且提供一个传输层的接口(API)—— Socket, 那么应用层基于 Socket 开发,也就是我们常说的网络编程。

Socket ——套接字,主要提供两组传输层的协议接口。

1. 基于 UDP 传输协议的Socket 接口开发

2. 基于 TCP 传输协议的Socket 接口开发 


简单讲述一下各个层级的协议主要的功能:

应用层:主要就是开发的程序需要具备一个联网,进行网络交互的功能和模式,这个一点是程序猿根据业务的实际需求设计开发的(选择使用那种传输层协议)。

传输层:主要负责数据在传输过程中的真实性,有效性等,例如:检测到数据没有传输成功那就再发一份,保证数据从源头到达目的,传输层给应用层提供服务。

网络层:主要负责数据的传输,利用IP 地址在网络中找到目的主机的位置,路由转发,提供一条可靠的传输路径。

数据链路层:主要给两个相邻的节点之间交互数据,例如将网卡中的数据交给物理层转化识别。

物理层:硬件设备,将二进制数据以各种形式传播,高低电平电信号——网线,光纤的光信号,以及广播等等。


二、TCP 传输协议简介

TCP(Transmission Control Protocol)是一种面向连接、可靠的传输协议,它在互联网协议模型中属于传输层,也是在日常开发中最广泛使用的协议,TCP 协议可以保证可靠的数据传输。

本篇博客将围绕着 TCP 协议如何保证可靠的数据传输来展开。

TCP 协议的特点

  1. 面向有连接 :传输数据之前,通信双方先建立可靠连接
  2. 可靠传输 : TCP 协议有超时重传的机制和确认应答机制等一系列的措施,当发现连接没有问题,但数据没有成功传输的时候会重新发送数据。
  3. 面向字节流:字面意思,使用字节流传输。
  4. 缓冲区:在进行网络数据通信时,用于存储待发送或已接收数据的缓冲区,有了缓冲区的概念,可以帮助协调发送方和接收方之间的数据传输速度,并最大限度地减少数据丢失或混乱的风险……
  5. 传输数据的大小不受限制:字节流,流式传输,前提是有连接。
  6. 全双工通信:通信双方都可以同时进行信息交互,例如:电话通信

 2. 1 TCP 协议报文格式

我们学习一种协议最好是从该协议的数据报开始分析。

TCP 报文的结构图:

仔细观察 TCP 数据报文结构图,我们会发现整个TCP 固定首部占20个字节,160 二进制位,但是根据我们画的结构图,所有的的节点相加只有 158 个二进制。

在数据偏移的这一行,4 + 4 + 6 + 16 = 30位, 其实有两个二进制位是被 “浪费掉了”。

TCP 报文解析:

源端口和目的端口:两个端口各占 16个二进制位 端口可以认为是应用程序的身份标识,每一个入网的程序在启动的时就会随机的绑定一个端口号, 也可以手动给程序指定一个端口号,但是注意在同一主机中端口号不可重复,另一点,就是小于等于 1024 的端口号,被称为“知名端口号”,提供给一些名气比较大的服务器使用,例如:http 80。 使用端口号用于确认信息的发送方是那个应用程序,信息的接收方是那个应用程序。

序号和确认号:各占 32个二进制位 用于实现数据的可靠传输,所传送的字节流的每一个字节都会按顺序编号,保证数据传输的顺序和接收的顺序一样。序号表示当前发送的数据包的序号,确认号表示期望接收的下一个数据包的序号。

发送方: 1. 哥们早安, 2. 周末有没有兴趣出去玩啊。

接收方: 2. 周末有没有兴趣出去玩啊 ,1. 哥们早安。

这种情况很明显是不可靠的的,序列号和确认号存在的意义就在于保证数据传输的顺序和接收的顺序一样。               

数据偏移量:占4 个二进制位 确定 TCP 报文头部的长度,告诉接收端的应用程序,除去TCP 头部报文,身后数据部分从何处开始。

标志位:包括ACK、SYN、FIN、RST、PSH、URG六种各占一个二进制位。

如果为标志位置为 1表示 true 的意思。

ACK用于确认收到数据包;

SYN判断通信双方是否建立了连接;

FIN用于关闭连接;

RST用于重置连接;

PSH用于提示接收方立即将数据推送给应用程序,而不是进入接收缓冲区;

URG用于指示TCP包中有紧急数据

窗口大小:用于流量控制,的校验和值是否正确,判断数据在传输的过程中是否受到影响(例如:电磁信号干扰表示发送方能够发送的未经确认数据的最大字节数,该字段可以用于 TCP 的流量控制,下文滑动窗口详细讲述。

TCP校验和:用于检测TCP头和数据造成数据的偏差。保证数据的正确性。

紧急指针:仅在URG标志被设置为 1 时才使用,用于指示紧急数据的末尾位置。

保留:TCP报文头中的保留字段主要用于保留未来使用、兼容旧版本和防止出现错误,并为TCP协议提供了可扩展性和灵活性。


三、TCP 保证数据可靠传输的机制 

3.1 确认应答

确认应答:TCP 协议中,每次发送数据,接收方都会发送一个确认应答,告诉发送方数据已接收到了,如果发送方“迟迟”没有收到确认应答,就会认为数据没有发送成功,就会将数据重新传输。

这也是 TCP 协议实现可靠传输最核心的机制。

ACK(acknowledge)标志位用于确认收到数据包,会给予通信双方一个 ACK 反馈,利用这个反馈我们就发送端就可以判断接收端已经成功接收到信息了。同时这也意味着传输“效率”会有所降低,辛苦传输过去,还得等待对方反馈回来,如果迟迟没有反馈就会尝试重新发送一份~

TCP的确认应答(ACK)是指接收方在成功接收到发起方发送过来的TCP数据包后,向发起方发送带有确认标志位的TCP报文段作为响应的一种机制。


在网络通信中也常常遇到信息“后发先至” 的情况,前两年qq 聊天就存在这个情况,我也遇到过这种情况,什么意思呢,当我给我的朋友发送一大堆消息,理论上来说,对方接受到的消息顺序应该与我发送消息的顺序一致,其实不然,消息有时候没按照我们预想的顺序来,这样就容易引起一些误会,举个例子:

 网络通信中消息后发先至的原因可以有多种可能性,以下是几种可能性:

  1. 网络拥塞:当网络中的数据量过大时,会导致网络拥堵,从而导致一些消息被延迟发送或丢失,而其他消息在其之前被传输完毕并被接收方处理。这种情况下,即使先发送的消息比后发送的消息早,但后发送的消息可能会在先发送的消息之前到达接收方。

  2. 传输错误:网络传输过程中可能会出现传输错误,例如数据包损坏、丢失等等原因。如果一个数据包出现了错误,通过应答报文的反馈,发送方就需要将它重新发送,这可能会导致某些后发送的消息比先发送的消息更快地到达接收方。

  3. 排队延迟:当多个消息同时到达接收方时,接收方可能会将它们放入队列中进行处理。如果先发送的消息排在了后发送的消息前面,但由于其他因素(例如消息大小、处理时间等)导致后发送的消息比先发送的消息更快地被处理,那么后发送的消息就会先于先发送的消息到达接收方。


为了解决“信息后发先至” 的情况,可以对消息进行编号,给发送的消息分配一个"序号" ,同时应答报文给出“确认序号”。

TCP 协议数据传输就是引入了序号和确认序号。

TCP 协议会将每个字节的数据从前往后都进行编号,称之为“序列号”,因为TCP 是面向字节流传输的,不存在一条消息,两条消息的说法。

 发送方的TCP 报文确认序号并没有多大的意义:

确认序号的规则:根据发送方发过来的数据的最后一个字节序号的下一个字节的序号。

依据序号 1001 的含义:

1. 如果应答报文的确认序号,< 1001 ,接受方给发送方透露的信息就是我已经收到

2. 接收方接下来想向发送方索要从 1001 开始的字节流。

使用这种机制,我们就可以保证数据传输的顺序,数据到达接收方也不是立马给到应用程序处理,上文提到TCP 有一个缓冲区的概念,缓冲区就可以将数据按照 “序号” 排序,即使数据在传输的过程中受到影响改变了数据传输的顺序,还有缓冲区兜底呢~ 保证应用程序读取数据,读到数据的顺序一定是和发送的顺序一样的。

如果传输一切顺利,接收方就会反馈确认应答(反馈一个“TCP 首部”  其中ACK = 1)。


3.2 超时重传

数据在传输的过程中,难免会造成 “丢包” 问题(数据缺失),好在TCP 协议有确认应答的机制,如果那一部分的数据迟迟没有反馈应答(ACK),发送方就视为刚才的那部分数据丢包了,就会重新再发一遍,如果重发了好几次都没有得到接收方的应答,就会考虑连接这方面的问题,尝试重新建立连接等,下文讲述。

超时重传:TCP协议中,如果发送方没有收到确认应答,就会进行超时重传。发送方会设置一个超时时间,如果在这个时间内没有收到确认应答,就会重新发送数据。

发送方对于丢包的判定,是一定时间内,没有收到确认应答(带有确认标志位(ACK)的TCP报文段)—— ACK =  0

这个时候存在三种情况:
1. 数据直接在传输的过程中丢失,接收方没有收到数据,也就不会反馈 带有确认标志位(ACK)的TCP报文段。

2. 接受方收到数据后,反馈带有确认标志位(ACK)的TCP报文段(TCP 首部信息包含 ACK),然后这个报文段丢了。

3. 当发送方一定时间没有接收到反馈,就会触发超时重传,然后重传的数据也丢了

第一种情况:

 第二种情况:

第三种情况:

连续丢失多个数据包 “接收方无反馈” 的情况,大概率就是网络环境出现了非常严重的问题,TCP协议针对这种连续发多个数据都再丢失的情况,处理的思路是继续超时重传,但是每丢一次数据包,超时等待的时间就会越长(重传的频率降低了),如果连续多次传输超时重传都无法获取到接收方反馈的(ACK-TCP 首部信息包含 ACK),就尝试给通信双方重新建立连接,此时如果重新建立连接也是失败,TCP 协议就会放弃本次网络通信。


四、总结

TCP 传输控制协议,是互联网通信中使用最为广泛的协议,使用TCP 协议传输数据,数据安全可靠、真实性高,传输速度较快。

学习一个协议的核心先熟悉他的报文格式。

确认应答:

当接收方收到发送方的数据时,会给予发送方一个带有 TCP 首部的字段,其中ACK = 1, 表示我已经收到数据。 

如果发送方一定时间内没有等到接收方反馈的确认应答,就会对该段“数据包” 进行重传,期间如果还是没有接收到反馈,发送方就会降低重传的频率,超过一定的次数,TCP 就尝试给通信双发重新建立连接,如果连接失败,就会终止本次的网络通信。

TCP 为了解决数据发送的数据和接收的数据顺序不一样,所以给每一个字节进行编码,面向字节流传输嘛,序号字段描述了当前"数据包"的序列号, 发送端的确认序号没有实际的意义,接收方反馈的确认序号描述的期望下一个“数据包”的序号,如此发送方就知道下一次对方需要 “那一段” 数据,然后就是接收缓冲区的作用,传输的数据都有了编号,就可以利用“数据包”的序号对数据进行排序,这样数据的顺序也就得到了保障。

遇到接收方数据接收成功,但反馈ACK 包丢失的情况,发送端超时重传,接收缓冲区就会对数据进行去重操作,保证应用程序拿到的数据是独一份的。


好了,到这里,网络编程中的【TCP 协议】报文格式,数据可靠传输的机制(一)博主已经分享完了,今天主要是学习 的是 TCP的报文结构,以及两种保证数据可靠传输的机制,这也是较为核心的机制,希望对大家有所帮助,如有不妥之处欢迎批评指正~

 

下期预告:【TCP 协议】连接管理之 “三次握手,四次挥手”

感谢每一个观看本篇文章的朋友,更多精彩敬请期待:保护小周ღ *★,°*:.☆( ̄▽ ̄)/$:*.°★* 

遇见你,所有的星星都落在我的头上……

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

getType() 和 getGenericType()的区别

处理泛型时会经常用到这两个方法&#xff0c;但是二者的区别是什么&#xff1f; 先看看官方的解释&#xff1a; getType 》&#xff1a;Returns a Class object that identifies the declared type for the field represented by this Field object. 返回字段对象声明类型的…

nodejs+python+php+springboot+vue 婚庆公司服务网站管理系统

管理员模块 &#xff08;1&#xff09;信息管理模块&#xff1a;对商家和个人的查看&#xff0c;修改。 &#xff08;2&#xff09;留言管理模块&#xff1a;对留言进行管理&#xff0c;确定是否能进行发布&#xff0c;对留言进行回复。 &#xff08;3&#xff09;权限管理&…

Git常用命令2

git commit --amend 有时候我们提交完了才发现漏掉了几个文件没有添加&#xff0c;或者提交信息写错了。 此时&#xff0c;可以运行带有 --amend 选项的提交命令来重新提交,这个命令会将暂存区中的文件提交。 如果自上次提交以来你还未做任何修改&#xff08;例如&#xff0c;…

【C++入门】一篇搞懂auto关键字

个人主页&#xff1a;平行线也会相交 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 平行线也会相交 原创 收录于专栏【C之路】 目录 作用不那么大的场景auto真正的价值注意点auto不能推导的场景范围for范围for的使用条件 作用不那么大的场景 在C中推出了…

工业元宇宙对于制造业的影响有哪些?

伴随元宇宙的快速发展&#xff0c;它在诸多现实场景中都实现了广泛应用&#xff0c;特别是在全球科技与产业竞争核心的智能制造领域。元宇宙与智能制造融合的本质是重构企业研发、制造、销售、终端四大场景&#xff0c;相当于把企业打包进虚拟世界&#xff0c;在虚拟世界中建设…

(五)ArcCatalog应用基础——ArcCatalog基本操作

&#xff08;二&#xff09;ArcCatalog应用基础——ArcCatalog基本操作 当ArcCatalog 与文件夹、数据库或者 GIS 服务器建立链接之后&#xff0c;就可以通过 ArcCatalog 来浏览其中的内容。ArcCatalog 具有浏览地图和数据、创建元数据、搜索地图数据、管理数据源等功能&#x…

SpringBoot RabbitMQ 死信队列

1. 死信定义 无法被消费的消息&#xff0c;称为死信。 如果死信一直留在队列中&#xff0c;会导致一直被消费&#xff0c;却从不消费成功&#xff0c;专门有一个存放死信的队列&#xff0c;称为死信队列(DDX, dead-letter-exchange)。 死信队列 DLX&#xff0c;Dead Letter Exc…

火山引擎 BVE 视频图片硬件编码器演进之路

动手点关注 干货不迷路 前言 近日&#xff0c;第 17 届世界编码器大赛 MSU 2022 公布硬件编码器比赛结果&#xff0c;在 60 fps&#xff08;帧率&#xff09;的超快视频编码赛道上&#xff0c;火山引擎多媒体实验室自主研发的 BVE 1.1 编码器表现突出&#xff0c;荣获最佳 FPGA…

计算机网络学习06(HTTP1.0 vs HTTP1.1)

1、响应状态码 HTTP/1.0仅定义了16种状态码。HTTP/1.1中新加入了大量的状态码&#xff0c;光是错误响应状态码就新增了24种。比如说&#xff0c;100 (Continue)——在请求大资源前的预热请求&#xff0c;206 (Partial Content)——范围请求的标识码&#xff0c;409 (Conflict)…

【C++】priority_queue使用和模拟实现——仿函数

文章目录 1. priority_queue的使用1.priority_queue的介绍2.priority_queue的结构3. 主要接口4. 使用示例 2. 仿函数1. 仿函数的概念2.尝试实现仿函数 3.priority_queue的模拟实现1.priority_queue的结构2. 接口实现1.向下调整算法2. 向上调整算法3.构造函数4.修改数据5.获取数…

机器学习 -Statsmodels

机器学习记录 Statsmodels 用于探索数据, 估计模型, 并运行统计检验. conda install -y statsmodels线性回归 import numpy as np import pandas as pd import matplotlib.pyplot as plt import statsmodels.api as sm import statsmodels.datasets.utils as du import sea…

数据结构【二】:霍夫曼编码

霍夫曼编码&#xff08;Huffman Coding&#xff09;是可变长编码&#xff08;VLC&#xff09;的一种。本质上使用变长编码表对源符号进行编码&#xff0c;通过评估源符号出现概率的方法进行分类&#xff0c;将出现几率较高的源字符使用较短的编码&#xff0c;出现几率较低的源字…

Hive优化补充

目录 一、表设计优化 1.通过设计分区表&#xff0c;增加动态分区&#xff0c;查询时避免全表扫描 2.设计分桶表&#xff1a;适用于大表join大表的情况 最后&#xff0c;两张大表进行join转为两张分桶表进行join&#xff1a; 二、文件存储 1.文件格式-概述 2.文件格式——…

学系统集成项目管理工程师(中项)系列13b_人力资源管理(下)

1. 项目团队建设 1.1. 塔克曼(Tuckman)阶梯理论 1.2. 理论基础 1.2.1. 激励理论 1.2.1.1. 马斯洛需要层次理论 1.2.1.1.1. 生理需要 1.2.1.1.2. 安全需要 1.2.1.1.3. 社会交往的需要 1.2.1.1.4. 自尊的需要 1.2.1.1.5. 自我实现的需要 1.2.1.2. 赫茨伯格的双因素理论…

Leetcode力扣秋招刷题路-0802

从0开始的秋招刷题路&#xff0c;记录下所刷每道题的题解&#xff0c;帮助自己回顾总结 802. 找到最终的安全状态 有一个有 n 个节点的有向图&#xff0c;节点按 0 到 n - 1 编号。图由一个 索引从 0 开始 的 2D 整数数组 graph表示&#xff0c; graph[i]是与节点 i 相邻的节…

Git HEAD及detached head

背景&#xff1a;最近在使用git checkout重置HEAD指向&#xff0c;偶尔会出现Detached HEAD提示&#xff0c;于是想探究一下具体的原理及过程&#xff0c;遂写下了这篇文章。一般checkout用于切换分支和检出历史的某个节点&#xff0c;或恢复工作区的文件&#xff0c;这三个功能…

OpenHarmony JS Demo开发讲解

项目结构 打开entry→src→main→js&#xff0c;工程的开发目录如图所示 其中&#xff0c; i18n文件夹&#xff1a;用于存放配置不同语言场景的资源&#xff0c;比如应用文本词条&#xff0c;图片路径等资源。en-US.json文件定义了在英文模式下页面显示的变量内容&#xff0c…

Java 泛型为什么设计成是可以擦除的

Java 泛型是 Java 5 引入的一种类型安全的编程机制&#xff0c;它允许在编译时指定泛型类型参数&#xff0c;从而提高代码的类型安全性和可读性。然而&#xff0c;Java 泛型的实现方式是通过类型擦除来实现的&#xff0c;这也引发了一些争议。本文将介绍 Java 泛型为什么设计成…

2023年某科技公司前端开发初级岗的面试笔试真题(含选择题答案、问答题解析、机试题源码)

📚关于该专栏: 该专栏的发布内容是前端面试中笔试部分真题、答卷类、机试等等的题目,题目类型包括逻辑题、算法题、选择题、问答题等等,除了内容的分享,还有解析和答案。真实来自某些互联网公司,坐标广东广州。 🔥🔥🔥 持 续 更 新 🔥🔥🔥 😉专栏博主: 黛…

HCIP-7.1交换机ARP、VLAN之间的三层通信技术学习

交换机ARP、VLAN之间的三层通信技术学习 1、ARP1.1、 地址解析过程1.2、ARP报文格式1.3、ARP表项1.4、免费ARP1.5、 VLAN间ARP代理1.5.1、解决同网段&#xff0c;不同广播域内主机互通问题&#xff1b;1.5.2、解决同网段&#xff0c;不同VLAN之间主机互通问题。1.5.3、解决同网…