TCP协议的报头格式和滑动窗口

news/2024/5/17 17:39:13 标签: 网络协议, tcp/ip, tcp, linux

文章目录

  • TCP报头格式
    • 端口号
    • 序号和确认序号
      • 确认应答(ACK)机制
      • 超时重传机制
    • 首部长度
    • 窗口大小
    • 报文类型
      • URG
      • ACK
      • SYN
      • PSH
      • FIN
      • RST
  • 滑动窗口
    • 滑动窗口的大小怎么设定怎么变化
    • 滑动窗口变化问题

TCP报头格式

image-20230811215559584

端口号

两个端口号比较好理解,通过端口号来找到指定的进程

序号和确认序号

先要认清这两个序号首先得了解TCP的确认应答(ACK)机制

确认应答(ACK)机制

根据生活例子来说,当我们再和别人聊天时需要得到对方的回复才能够确定对方能够听到我们的话。对于TCP通信也是如此,当一端向另一端发送数据后,对端收到数据后需要告诉发送端已经收到了,这样发送端才能够知道,因此作为接收端就会应答确保已经接收到数据了

这种机制就是确认应答机制

在真实的使用场景中,TCP发送端如果是一条数据发送后等收到接收端的应答再发送另一条数据,这样效率就非常的低。所以真实的场景中,发送端会一下子发送多条数据。那么为了确保每一条数据都被接收端接收到了,那么接收端就需要对应每一条数据都进行应答,那么如何保证接收端应答的是对应的数据。或者说如果发生了丢包,接收端不会应答该条数据那么作为发送端如何知道是哪一条数据没有收到接收端的应答呢

这就引进了序号和确认序号的概念:

序号可以用来标识数据之间的不同,接收端收到数据后应答该条数据就会返回确认序号,而这个确认序号就是数据序号+1 。这样的目的是告诉发送端下次发送数据的序号从这个确认序号开始。

有了序号和确认序号的配合后,应答机制就能保证应答的是指定的数据

需要注意:接收方应答了一个确认序号后,就代表着这个确认序号之前的所有序号的数据都已经接收到。

也就是说假如接收端接收到了序号1000和3000的数据,但是没有收到2000的数据,那么接收端应答的确认序号只会是1001。那么这里又得引出一个概念:

超时重传机制

根据上述的例子,如果接收端没有收到2000的数据,那它就只会发送1001的应答。那么作为发送端迟迟都等不来2000的数据的应答,那发送端就会意识到数据丢包了。这时候作为发送端就会再次向接收端发送数据。

关于数据丢包就会出现另一种情况,上述的情况是发送端发送的数据丢包了。那么如果接收端接收到了数据,但是它发送的应答丢包了呢。这种情况同样会导致发送端迟迟收不到应答而重新发送数据,那假如应答老是丢包那么发送端就会发送很多份相同的数据,这时候作为接收端就会收到很多重复的数据。所以接收端需要对数据去重,而去重就可以利用序号实现,因为每个相同的数据都会有相同的序号

image-20230811222432166

首部长度

  1. TCP协议的报头是有标准长度的也就是最少长度,长度为20字节。因此读取时首先会读取20字节
  2. 首部长度为4个比特位,也就是说范围在[0000 - 1111]也就是[0 - 15]
  3. TCP报头的总长度 = 首部长度 * 4字节
  4. 因为TCP协议的标准长度为20字节,因此首部长度初始为5(0101)

窗口大小

首先的了解TCP协议发送数据和读取数据是在哪里得到的。

事实上,接收端调用read函数将数据读取并不是从TCP的报文中读取的,而是从一个缓冲区中也就是接收缓冲区中读取的。而发送端调用write函数写数据发送也不是直接写到TCP的报文中,而是写到发送缓冲区中

那么对于缓冲区而言就必定有大小,窗口大小就是指接收缓冲区的大小。TCP的报头中要含有自己缓冲区剩余的大小,为了告诉发送端自己的缓冲区大小还剩多少,让发送端做出发送策略调整,防止出现发送的太快导致来不及读使得缓冲区满了,也不能发的太慢

报文类型

事实上,TCP的报文也是有类型的,接收端要根据不同类型的报文做出不同的动作

image-20230811223736461

这几个就对应着TCP不同的报文类型,而这几个都是一位来着,置1或置0

URG

数据对于接收方而言,乱序就是不可靠的现象。所以要对收到的数据进行排序,因为报文是有序号的所以可以保证数据的按序到达。那么如果需要排队那就难免会有需要插队的情况。

URG:代表着有需要尽快读取的数据

而这个要配合这紧急指针使用,通过紧急指针知道一个偏移量在报文的有效数据中通过偏移量找到该数据

ACK

ACK用于建立连接时应答确认

SYN

用于请求连接

PSH

催促接收端尽快读取数据,避免缓冲区满

FIN

用于断开连接请求

RST

由于连接并不一定会成功,RST就用于重置连接

滑动窗口

因为发送端发出数据后接收端不一定会接收到数据,也就是出现丢包。因此发送端在发送出去数据后并不能直接将数据抹除,需要等待接收端应答后才可以抹除。那么这份数据保存在哪里呢?

这种数据就保存在滑动窗口中

image-20230811225908424

图中为缓冲区的分布,其中中间部分就是滑动窗口

滑动窗口的大小怎么设定怎么变化

对于缓冲区本质上就是一个数组,所以滑动窗口就有这个数组中的两个下标控制大小

image-20230811230408810

而决定缓冲区的大小和接收端的接受能力有关,也就是不管未来滑动窗口怎么变化都一定要保证在接收端的接受范围内。

因为数据都是有数据序号的,因此滑动窗口的变化:win_start = 应答收到的数据确认序号,win_end = win_start + 对端的窗口大小

滑动窗口变化问题

窗口会往左移动吗?

答案肯定是不会的

窗口一定会向右移动吗?

肯定窗口的变化可以得出,只有收到应答时窗口才会滑动,所以也有可能是不动的,但是如果动了一定是向右动

滑动窗口移动的本质就是数组下标的更新,所以窗口有可能会不动的

同样窗口也有可能变成0,例如对方的缓冲区满了

如果一直移动,空间不够了怎么办

针对这个问题,操作系统内核将发送缓冲区组织为环形结构了


http://www.niftyadmin.cn/n/4931830.html

相关文章

Flutter实现倒计时功能,秒数转时分秒,然后倒计时

Flutter实现倒计时功能 发布时间:2023/05/12 本文实例为大家分享了Flutter实现倒计时功能的具体代码,供大家参考,具体内容如下 有一个需求,需要在页面进行显示倒计时,倒计时结束后,做相应的逻辑处理。 实…

ONVIF对讲功能漫谈

ONVIF对讲功能漫谈 前言一、onvif对讲功能和onvif协议关系大吗?二、如何上报设备支持onvif对讲功能呢?三、onvif协议中哪个接口上报音频解码配置?四、献上抓包报文:前言 本篇文章尝试使用提问的方式来分享onvif对讲功能那点事。 一、onvif对讲功能和onvif协议关系大吗? on…

【网络层+数据链路层】深入理解IP协议和MAC帧协议的基本原理

文章目录 前言一、IP协议二、MAC帧协议 1.以太网2.以太网帧(MAC帧)格式报头3.基于协议讲解局域网转发的原理总结 前言 为什么经常将TCP/IP放在一起呢?这是因为IP层的核心工作就是通过IP地址来定位主机的,具有将一个数据报从A主机…

【ArcGIS Pro二次开发】(60):按图层导出布局

在使用布局导图时,会遇到如下问题: 为了切换图层和导图方便,一般情况下,会把相关图层做成图层组。 在导图的时候,如果想要按照图层组进行分开导图,如上图,想导出【现状图、规划图、管控边界】3…

C# winform 布局操作组件介绍

Winform布局 布局的2个属性 Anchor:锁定位置 Dock:填充位置 一般Dock是与容器控件配合使用 布局的一些控件 TableLayoutPanel:表格容器 每个表格只能放一个控件 要放置多个时可以在每个表格里面添加一个Panel(也可以是其他的容器&#x…

windows docker mysql8.0 挂载配置文件不生效的问题

原因 mysql 8.0 遇到sql_modeonly_full_group_by的问题,于是就自定义my.cnf 去掉only_full_group_by,修改my.cnf 文件后,进行映射启动 docker run 命令 docker run -p 3306:3306 --privilegedtrue --restartalways -d --name axsc-mysql -…

P8605 [蓝桥杯 2013 国 AC] 网络寻路

X 国的一个网络使用若干条线路连接若干个节点。节点间的通信是双向的。某重要数据包,为了安全起见,必须恰好被转发两次到达目的地。该包可能在任意一个节点产生,我们需要知道该网络中一共有多少种不同的转发路径。 源地址和目标地址可以相同…

Docker安装 elasticsearch-head

目录 前言安装elasticsearch-head步骤1:准备1. 安装docker2. 搜索可以使用的镜像。3. 也可从docker hub上搜索镜像。4. 选择合适的redis镜像。 步骤2:拉取elasticsearch-head镜像拉取镜像查看已拉取的镜像 步骤3:创建容器创建容器方式1&#…