【网络原理4】TCP特性篇

news2025/1/23 4:01:50

 

目录

 一、滑动窗口

传统发送接收机制的缺点

滑动窗口的特性

 发送方什么时候会接着发送下一条报文

如果在滑动窗口的机制下面发生了丢包会怎样处理

 情况1:ack丢了

情况2:主动发送的syn丢包了

滑动窗口的应用场景

二、TCP流量控制:根据接收方的处理能力,协调发送方的发送速率。

TCP滑动窗口过大的缺点

如何衡量接收方的处理能力     

有一种量化的方法:

更简单的方法:(直接查看接收方的接收缓冲区的剩余大小):

探测报文 

 窗口大小为16位,也就是最大位64kb,那么是否意味着窗口大小最大是64kb呢?

三、拥塞控制 

为什么有了流量控制,还需要拥塞控制

 拥塞窗口(cwnd)

第一阶段,慢增长:

第二阶段:避免拥塞算法

第三阶段:发生了网络拥塞

拥塞窗口的好处:

如何确定TCP滑动窗口的值

四、延时应答机制

实际场景当中的延时应答机制

 五、捎带应答

六、粘包问题

什么是粘包问题

解决粘包问题:两个约定

     一、关于协定的约定:

     二、约定每个包的长度

     三、明确分隔符

 七、其余的不可抗力

 情况1:进程崩溃了/主机关机

 情况2:主机掉电了/网线断开了。

   如果是接收方掉电了:

  如果是发送方掉电了:

 一、滑动窗口

传统发送接收机制的缺点

       我们知道:TCP是一个拥有可靠性的协议;它的可靠性是依靠确认应答机制和超时重传机制来保证的。

       在这一篇文章当中,也提到了TCP的可靠性是如何实现的。
【网络原理篇2】TCP报头详解_革凡成圣211的博客-CSDN博客TCP报头结构https://blog.csdn.net/weixin_56738054/article/details/128935529?spm=1001.2014.3001.5502

       但是关于超时重传,在上述文章的图解当中:是客户端一次会话发送完成之后,下一次客户端再次向服务端发起会话的时候,需要等待直到服务端的ack进行反馈了的时候,才会再次发送文。

       为了减少这种不必要的等待,于是引入了TCP滑动窗口机制


滑动窗口的特性

 滑动窗口的特点就是:批量地发送一组数据,只需要使用一份时间来等待多个ack即可。

 因此,把可以连续发送(不需要等待,就能直接发送)的数据的最大的量,就称为"窗口大小"。

 发送方什么时候会接着发送下一条报文

       发送方不是一次等待所有的数据(1-4000)都全部到达了,才会再次发送ack报文。而是等待到一个ack回应过来之后,才会接着发送下一个TCP报文

         在上图当中,数据1-1000从主机A发送给主机B。当主机B回应了1001报文,也就是发送了ack到达主机A之后,主机A就会给B重新发送一个ack报文(4001-5000)。

         下面,模拟一下发送方发送——接收一次报文的情况。

时间轴发送方接收方窗口大小窗口范围一次发送的范围
t1明确任务:发送报文大小为4000的数据...(第一次发送)4000(1001,5001)
t2发送数据(1001-2000)1000
t3发送ack报文:确认应答,下一个为:2001(32位确认序号)1000
t4接收到ack应答报文
t5再次发送ack报文...(第二次发送)4000(2001,6001)

       在t5时刻,发送方本来需要等待的ack报文的范围是(1001,5001),但是由于在t3时刻已经收到了确认序号为2001的ack报文了,说明编号<2001的报文都收到了

       那么,再次发送新的报文的时候,滑动窗口的范围就变了,变成了原来的范围+1000,也就(2001,6001)。


  


如果在滑动窗口的机制下面发生了丢包会怎样处理

 关于丢包的问题,需要分为两种情况来讨论:

 情况1:ack丢了

 如果ack丢了,不需要做任何的处理,也不会影响发送方和接收方之间的正常传输。

 

 为什么不需要做任何的处理呢?再次图解一下:

时间轴发送方接收方报文类型说明
t1发送1-1000的数据syn
t2发送应答报文给发送方(32位确认序号为1001)ack此时发生了丢包。
t3发送数据1001-2000的数据syn
t4发送应答报文给接收方(32位确认序号为2001)ack没有发生丢包
t5收到了确认序号为2001的编号ack

       可以看到,t5的时候,发送方收到了确认序号为2001的应答报文(ack),那么也就默认了确认序号<2001的报文都已经收到了,无需再次发送syn。

       那么,如果数据丢失得比较多,只返回了最后一次的ack,这样岂不是影响比较大?

       这里,我们需要注意的是,丢包毕竟是小概率事件。 只返回窗口发送的最后一次的ack, 更加是不太可能的情况,因此这种情况无需担心。

       并且,少发送一两次的ack,可以一定程度地减少封装分用的次数,提高效率。


情况2:主动发送的syn丢包了

 如果主动发送的syn丢包了,那么发送方就会不断反复发送数据。

下面,模拟一下主动发送的syn丢包的情况:

时间轴发送方接收方报文类型说明
t1发送1-1000的数据syn此时发生了丢包
t2发送数据1001-2000的数据syn此时没有发生丢包
t3发送应答报文给接收方(32位确认序号为1001)................t1时刻对应的ackack
t4收到了确认序号为1001的报文ack
t5发送数据为2001-3000的数据syn此时没有发生丢包
t6发送应答报文给接收方(32位确认序号为1001)................t1时刻对应的ack
t7接收到了确认序号为1001的报文

       可以看到,站在发送方的角度,发送方如果发送的syn报文如果出现了丢包,那么接收方会不断重复发送方发送第一次发送的报文的ack

       由于发送方多次收到相同的数据,那么就需要由发送方进行重传了。


       于是,发送方继续重传数据(t8时刻开始)。

       由于接收方在上面的t3、t6时刻收到了发送方发送的报文,编号分别为(1001-2000),(2001-3000)。那么,下一次接收方再次确认数据的时候,就会从3001开始确认了。

时间轴发送方接收方报文类型说明
t8发送(1-1001的数据)syn
t9接收到了数据,并返回报文(确认序号为1001)ack

总结一下:

对于数据报(syn)丢失的情况,接收方会只重传丢失数据对应的ack报文。

直到发送方再次发送之前丢失的数据报。

确认序号,也可以理解为接收方向发送方索要的数据


以上传输的方式,被称为"快速重传",只重传了丢失的数据

滑动窗口的应用场景

如果需要传输的数据比较密集,那么就使用滑动窗口来处理。

如果需要传输的数据不那么密集,那么就无需采用滑动窗口处理。


二、TCP流量控制:根据接收方的处理能力,协调发送方的发送速率。

       TCP流量控制是一种干预发送窗口大小的机制。滑动窗口越大,也就意味着一次可以传输的数据越多,也就意味着效率越高

       但是,窗口如果过大,也会影响发送和接收的效率。


TCP滑动窗口过大的缺点

        缺点1:完全不需要等待ack的回应;如果ack丢失过多,可靠性无法保证。

        缺点2:接收方来不及接收syn,发了≈白发。

        缺点3:窗口过大,也是需要一定的开销的。 

因此,在考虑设置滑动窗口的大小的时候: 

接收方的处理能力,就是一个很重要的约束依据。

发送方的速度,不能超出接收方的处理能力范围。 

这就引入了流量控制机制:根据接收方的处理能力,协调发送方的发送速率。


如何衡量接收方的处理能力     

有一种量化的方法:

计算接收方每秒钟能处理多少字节

但是这种方式实际上用起来有一些麻烦,因此不太推荐使用。


更简单的方法:(直接查看接收方的接收缓冲区的剩余大小):

       每一次发送方(主机A)接收方(主机B)发送数据的时候,主机B在发送回应报文(ack)的时候,就需要把缓冲区剩余的空间,通过这个ack报文返回给A。

       也就是说,接收方发送ack报文,其中的TCP报头当中的16位窗口大小就是接收方TCP缓冲区的剩余容量大小。


在这一篇文章当中,提到了TCP报头结构:
【网络原理篇2】TCP报头详解_革凡成圣211的博客-CSDN博客TCP报头结构https://blog.csdn.net/weixin_56738054/article/details/128935529?spm=1001.2014.3001.5501

里面有一个属性:16位的窗口大小.

这一个属性描述的就是窗口的大小;这一个属性仅仅只在报文类型是ack的时候才会生效。

把缓冲区剩余大小通过ack应答报文发送给发送方。让发送方明确下一次发送时候的窗口大小。

 如下图:

探测报文 

       当ack应答报文发送的窗口大小为0的时候,就意味着此时接收方的缓冲区已经无法再次处理更多数据了,因此发送方就会暂停发送。

       在等待的过程当中,发送方会发送一个不携带任何数据的探测报文,探测接收方的缓冲区大小。如果接收方的缓冲区大小不为0了,才会继续发送报文。


 窗口大小为16位,也就是最大位64kb,那么是否意味着窗口大小最大是64kb呢?

  不是的。在选项部分,TCP为了让窗口更大,引入了窗口扩展因子。

  如果窗口大小为64kb,扩展因子里面写个2,意思就是让64kb<<2,得到的就是64*4=256kb。


三、拥塞控制 

为什么有了流量控制,还需要拥塞控制

       在二当中,前面考虑A的发送速率,只是参考B的处理能力(缓冲区剩余空间大小),也就是由B的处理报文的情况来决定A发送的窗口的大小。

       但是,A与B之间还有其他的网络节点。具体来说,就是A与B之间的传送需要经过一段链路。于是就需要通过拥塞控制+流量控制,再次确定发送方的窗口大小


 拥塞窗口(cwnd)

 拥塞窗口,是发送方维护的一个状态的变量。

 拥塞控制,本质上就是通过实验的方式,来逐渐找到一个合适的窗口大小(合适的发送速率)

 大致是这样的一个过程:

 进行N轮的传输与发送,统计每一轮的拥塞窗口大小

第一阶段,慢增长:

       由于窗口大小比较小,每一轮不丢包(发送方收到一个ack)都会让窗口大小扩大一倍,也就是指数增长,这个过程也被称为"慢启动"。

       下图来源于《小林coding》


第二阶段:避免拥塞算法

       当滑动窗口到达慢启动门限(可以理解为一个阈值)之后,轮次与拥塞窗口大小就变成了线性增长的关系了。

       每收到一个ack,cwnd就增加1/cwnd。


第三阶段:发生了网络拥塞

       在第三阶段,一旦发生了丢包,说明此时窗口的大小已经比较大了,那么说明此时发生了网络拥塞。那么就需要把窗口大小一下缩小成很小的值防止丢包的发生。然后重复第一、第二、第三阶段。


拥塞窗口的好处:

       拥塞窗口不是固定的值,而是一直动态变化的。

       随着时间的推移,逐渐到达一个动态平衡的过程。既可以找到一个合适的窗口大小,又可以让窗口的大小随着网络环境的变化而变化。


如何确定TCP滑动窗口的值

 流量控制拥塞控制共同决定发送方的窗口大小是多少。

 取的是拥塞窗口流量窗口的较小值。


四、延时应答机制

       这个机制是在滑动窗口的基础上面新增的一个机制。

       也就是发送方把syn报文发送给接收方的时候,接收方并不是立即返回ack,而是稍等一会儿再发送ack报文。在等待的这一段时间内,接收方的应用程序会首先把发送的syn报文给消耗一部分。


实际场景当中的延时应答机制

       在实际的滑动窗口当中,并不再是每发送一次syn,就返回一次ack了。而是有可能隔一条syn发送一条ack。


 五、捎带应答

    捎带应答机制,其实就是一种合并内核报文和普通业务报文的机制;

    在这一篇文章当中,我们也提到了四次TCP断开连接的四次挥手的过程:
【网络原理3】TCP连接管理_革凡成圣211的博客-CSDN博客TCP三次握手、四次挥手https://blog.csdn.net/weixin_56738054/article/details/128961091?spm=1001.2014.3001.5501

     重新回顾一下,什么情况下四次挥手可以变成三次:那就是第二次挥手(发送ack)和第三次挥手(发送FIN)之间的间隔比较小的时候,就会合并第二次挥手和第三次挥手。

     图解一下:

业务数据捎带上内核数据,合并起来一起发送。这个捎带的过程,就是捎带应答机制。


六、粘包问题

什么是粘包问题

       我们都知道TCP是面向字节流的协议。一次读取一个字节,一次读取N个字节都是可以的。

       这就导致一次读取的数据,有可能是半个应用层的数据报,有可能是3/4个,也有可能是一个完整的应用层数据报,或者一次读取,读到了多个应用层数据报......

       但是,在TCP的socket api当中没有告诉我们应该读取多少个字节。那么就会导致,一次读取的结果是不可预料的

        举个例子,假如有下面一段文字:

        儿的生活好痛苦一点儿也没有粮食多病少挣了很多钱。

        这句话,如果以TCP的形式进行传输,就有可能产生一些歧义。

       一次发送的报文大小直接决定了读取的含义。


解决粘包问题:两个约定

     一、关于协定的约定:

      例如约定好传输层的协议是TCP还是UDP这样的轨迹。


     二、约定每个包的长度

     例如明确一次读取的字节大小是多少,例如read的时候尽量把字节数组填满。

     也就是限制字节数组的大小。

 byte[] buffer=new byte[4];

 read(buffer)

      一次read的时候,会把这一个字节数组填满


     三、明确分隔符

      以什么分隔符作为结束的标志等等,像之前的手写tcp,就是以\n作为分隔符的。

      下面来一段伪代码:

      


 七、其余的不可抗力

 以下四种情况,可以分为两种情况讨论:

 情况1:进程崩溃了/主机关机

 情况1可以理解为进程没了,也就是对应的PCB没了,对应的文件描述符表也就释放了。

 相当于调用了socket.close(),此时内核会继续完成4次挥手。

 情况1会触发正常的四次挥手。


 情况2:主机掉电了/网线断开了。

   这两个情况,是来不及挥手的了。

   如果是接收方掉电了:

步骤发送方
1发送报文syn
2迟迟没有等待ack
3触发超时重传机制(再次发送syn)
4重传无果,仍然收不到ack
5重置tcp连接(此处采用的重传是发送复位报文段RST)
6仍然无果,那么放弃连接。

  如果是发送方掉电了:

   接收方需要周期性的给发送方发送一个消息,确认一下对方是否工作正常。

   此处发送一个消息,被形象地称为"心跳包",也就是验证一下接收方是否仍然在工作。

   这个"心跳包"类比的就是心跳:周期性地发送

   如果心跳"无了",那么说明发送方已经"无了"

  以上接收方为了验证发送方是否正常的机制,被称为"保活机制"。

 

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

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

相关文章

大数据下Flink on YarnSession 高可用集群环境部署开辟资源发布任务

前言&#xff1a;搭建大数据环境集群环境算是比较麻烦的一个事情&#xff0c;并且对硬件要求也比较高其中搭建大数据环境需要准备jdk环境和zk环境&#xff0c;还有hdfs&#xff0c;还有ssh之间的免密操作&#xff0c;还有主机别名访问不通的问题 等。必然会出现的问题&#xff…

拆个微波炉,分析一下电路

微波炉是用2450MHz的超高频电磁波来加热食品&#xff0c;它能无损穿越塑料&#xff0c;陶瓷&#xff0c;不能穿越金属&#xff0c;碰到金属会反射&#xff0c;但穿过含水食物&#xff0c;食物内的分子会高速摩擦&#xff0c;产生热量&#xff0c;使食物变熟。在厨房电器中&…

自学180天,我从功能测试进阶到自动化测试了...

大家好&#xff0c;我是彭于晏&#xff0c;一个7年测试工作的老司机。因为我一直在分享自动化测试技术&#xff0c;所以时常会被问到这个问题&#xff1a;“靓仔&#xff0c;功能测试想转自动化测试&#xff0c;请问要怎么入手&#xff1f;” 那么&#xff0c;接下来我就结合自…

不愧是GitHub点赞飙升的Java10W字面经,面面俱到,太全了!

最新的喜报啊&#xff0c;话不多说&#xff0c;先看图&#xff01;&#xff08;为了保护朋友的隐私&#xff0c;同时还有我自己的隐私&#xff0c;楼主就都打码了~&#xff01;&#xff09; 朋友说到这儿时候我就跟他说&#xff0c;不要只看眼前&#xff0c;要看长远一些&#…

前端开发之防抖与节流

前端开发中我们经常会通过监听某些事件来完成项目需求 1.通过监听 scroll 事件&#xff0c;检测滚动位置&#xff0c;根据滚动位置显示返回顶部按钮 2.通过监听 resize 事件&#xff0c;对某些自适应页面调整DOM的渲染&#xff08;通过CSS实现的自适应不再此范围内&#xff09;…

动态库和静态库的区别

什么是库文件 一般来说&#xff0c;一个程序&#xff0c;通常都会包含目标文件和若干个库文件。经过汇编得到的目标文件再经过和库文件的链接&#xff0c;就能构成可执行文件。库文件像是一个代码仓库或代码组件的集合&#xff0c;为目标文件提供可直接使用的变量、函数、类等…

Hadoop3.3.0--Linux编译安装

Hadoop3.3.0–Linux编译安装 基础环境&#xff1a;Centos 7.7 编译环境软件安装目录 mkdir -p /export/server一、Hadoop编译安装&#xff08;选做&#xff09; 可以直接使用课程提供已经编译好的安装包。 安装编译相关的依赖 yum install gcc gcc-c make autoconf automake…

leaflet 上传CSV文件,导出geojson格式文件(064)

第064个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+leaflet中加载CSV文件,将图形显示在地图上。点击导出geojson,下载成geojson文件。 直接复制下面的 vue+openlayers源代码,操作2分钟即可运行实现效果. 文章目录 示例效果配置方式示例源代码(共114行)安装插件…

如何判断是否ChatGPT回答出来的问题?解决方法详解

目录 前言 一、人工智能&#xff08;“ChatGPT”等&#xff09;能淘汰人类吗&#xff1f; 二、完全禁止或严格限制使用ChatGPT&#xff0c;是利大于弊还是&#xff1f; 1、ChatGPT与造纸术优点 2、人有悲欢离合&#xff0c;月有阴晴圆缺&#xff0c;此事古难全&#xff01…

Python基础-数据类型之序列

序列&#xff1a;一种数据结构&#xff0c;序列中的每个元素都会被分配到一个序号&#xff08;元素的位置&#xff09;。 常用的序列有&#xff1a;列表、元组、字符串。 一、序列的操作&#xff1a; 1&#xff1a;通过索引取值 nums_list [1,2,3,4] print(nums_list[0]) …

消息队列的特点

一、背景&#xff1a;在分布式系统中是如何处理高并发的由于在高并发的环境下&#xff0c;来不及同步处理用户发送的请求&#xff0c;则会导致请求发送阻塞。比如说&#xff0c;大量的insert、update之类的请求同时到达数据库MYSQL&#xff0c;直接导致无数的行锁表锁&#xff…

零基础机器学习做游戏辅助第十一课--原神自动钓鱼(一)

一、序言 前面我们已经学习了神经网络,卷积神经网络和强化学习等内容,也都做了对应的实例。但是我们的课是做游戏辅助,那么肯定要去游戏里实战一番。 今天就带领大家用我们所学的知识对近两年非常火爆的游戏《原神》进行实战。我们以自动钓鱼为例。 二、观察游戏玩法制定方案…

Seata源码学习(五)- Seata服务端(TC)源码解读

Seata源码分析- Seata服务端&#xff08;TC&#xff09;源码解读 上节课我们已经分析到了SQL语句最终的执行器&#xff0c;但是再往下分析之前&#xff0c;我们需要先来分析一下TM客户端与TC端通讯以后&#xff0c;TC端的具体操作 服务端表解释 我们的Seata服务端在应用的时…

RabbitMq及其他消息队列

消息队列中间价都有哪些 先进先出 Kafka、Pulsar、RocketMQ、RabbitMQ、NSQ、ActiveMQ 架构 消费推拉模式 客户端消费者获取消息的方式&#xff0c;Kafka和RocketMQ是通过长轮询Pull的方式拉取消息&#xff0c;RabbitMQ、Pulsar、NSQ都是通过Push的方式。 pull类型的消息队…

OpenCV制作Mask图像掩码

一、掩膜&#xff08;mask&#xff09; 在有些图像处理的函数中有的参数里面会有mask参数&#xff0c;即此函数支持掩膜操作&#xff0c;首先何为掩膜以及有什么用&#xff0c;如下&#xff1a; 数字图像处理中的掩膜的概念是借鉴于PCB制版的过程&#xff0c;在半导体制造中&am…

PowerShell Install VNC-Server VNC-Viewer

前言 VNCConnect是一款屏幕共享、远程控制电脑软件&#xff0c;可以让您连接到世界上任何地方的远程计算机&#xff0c;实时观看其屏幕&#xff0c;并像坐在它前面一样进行控制。RealVNC可以将人和设备连接到任何地方&#xff0c;实现控制、支持、管理、监控、培训、协作等等。…

Java——不同的子序列

题目链接 leetcode在线oj题——不同的子序列 题目描述 给定一个字符串 s 和一个字符串 t &#xff0c;计算在 s 的子序列中 t 出现的个数。 字符串的一个 子序列 是指&#xff0c;通过删除一些&#xff08;也可以不删除&#xff09;字符且不干扰剩余字符相对位置所组成的新…

【C语言学习笔记】:数组、指针相关面试题

无特殊说明情况下&#xff0c;下面所有题s目都是linux下的32位C程序。 「1、计算以下sizeof的值。」 char str1[] {a, b, c, d, e}; char str2[] "abcde";char *ptr "abcde";char book[][80]{"计算机应用基础","C语言","C程…

Apple Safari 16.3 - macOS 专属免费浏览器 (独立安装包免费下载)

Safari 浏览器 16 for macOS Montery, Big Sur 请访问原文链接&#xff1a;https://sysin.org/blog/apple-safari-16/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;www.sysin.org 之前 Safari 浏览器伴随 macOS 更新一起发布&#xff…

python的opencv操作记录12——Canny算子使用

文章目录Canny算子非极大值抑制非极大值抑制中的插值滞后阈值实际应用直接使用Canny算子使用膨胀先阈值分割Canny算子 上一篇说到&#xff0c;我在一个小项目里需要在一幅图像中提取一根试管里的两种液体的截面。为了达到这个目的使用传统图像里的区域分割技术&#xff0c;实际…