热门标签 | HotTags
当前位置:  开发笔记 > 后端 > 正文

TCPSACK介绍转载

一、SACK选项默认情况下TCP采取的是累积确认机制,这时如果发生了报文乱序到达,接收方只会重复确认最后一个按序到达的报文段,为此发送方的

一、SACK选项

默认情况下TCP采取的是累积确认机制,这时如果发生了报文乱序到达,接收方只会重复确认最后一个按序到达的报文段,为此发送方的处理只能是重复按序到达接收方的报文段之后的那个报文段,因而它无法准确知道哪些报文段到达了,哪些没有到达。
考虑以下情景,发送方的窗口状态如下:

 

如上图所示,主机A通过TCP发送10个长度都为100字节的报文段给主机B,其序号分别为0,100,200,300,400,500,600,00,800,900(图中以数字0-9代替)。主机B收到了序号为0和序号为100的报文段,但是序号为200,300,400的丢失了。之后主机B又收到了报文段500,600,700,800,900。当收到后续这些分组时,主机B只能对报文段100继续进行确认,即发送确认号为200的ACK。主机A收到这样的确认时,能重传的唯一报文段就是报文段200,在报文段200的确认被收到之前发送窗口是无法移动的,这时状况就会很糟糕,发送方每重传一个丢失的报文段,接收方就确认一个(由于是累积确认的,所以情况可能更糟,接收方每次都在等待一段时间后才发送确认),然后发送窗口向前移动一个,这个过程一直持续到报文段200,300,400都被接收方到。显然这种工作方式效率很低,降低了吞吐量。
SACK是TCP选项,它使得接收方能告诉发送方哪些报文段丢失,哪些报文段重传了,哪些报文段已经提前收到等信息。根据这些信息TCP就可以只重传哪些真正丢失的报文段。
需要注意的是只有收到失序的分组时才会可能会发送SACK,TCP的ACK还是建立在累积确认的基础上的。也就是说如果收到的报文段与期望收到的报文段的序号相同就会发送累积的ACK,SACK只是针对失序到达的报文段的。
SACK包括了两个TCP选项,一个选项用于标识是否支持SACK,是在TCP连接建立时时发送;另一种选项则包含了具体的SACK信息。

1.SACK允许选项

该选项格式如下所示:

它的工作机制类似于窗口扩大选项和事件戳选项,只能应用于SYN报文段,在连接建立阶段,主动发起连接的一方在它的SYN中指定选项。只有在它从另一方的SYN中收到了这个选项之后,FAK机制才会被使能。

2.SACK选项

SACK选项的格式如下图所示:

该选项长度可变,但由于整个TCP选项长度不超过40字节,所以实际最多不超过4组边界值。
该选项参数告诉发送哪些报文段是已经接收到并缓存的不连续的报文段,发送方可根据此信息检查究竟是哪个块丢失,从而发送相应的报文段。

  1. LeftEdgeofBlock:不连续块的第一个报文段的序列号
  2. RightEdgeofBlock:不连续块的最后一个报文段的序列号之后的序列号。

3.SACK的产生

SACK由接收方产生并通告给发送方,其产生有以下几种情形: 

3.1中间有丢包或延迟时的SACK

如果接收方接收到的报文段序号大于所期待的序号,说明有报文段被丢弃或者出现了大的延迟,此时可以发送SACK通知发送方。
为反映接收方的接收缓存和网络传输情况,SACK中的第一个块必须描述是那个报文段触发了该SACK的发送,接收方应该尽可能地在SACK选项部分中填写尽可能多的块信息,让发送方能了解当前网络传输情况的最新信息。

3.2对重复发送包的SACK(D-SACK)

RFC2883中对SACK进行了扩展。SACK中的信息描述的是收到的报文段,这些报文段可能是正常接收的,也可能是重复接收的,通过对SACK进行扩展,D-SACK可以在SACK选项中描述它重复收到的报文段。但是需要注意的是D-SACK只用于报告接收端收到的最后一个报文与已经接收了的报文的重复部分,比如(来自RFC):

 Transmitted       Received                              ACK Sent

 Segment            Segment                               (Including SACK Blocks)
 500-999             500-999                               1000
 1000-1499         (data packet dropped)
 1500-1999         (delayed)
 2000-2499         (data packet dropped)
 2500-2999         (delayed)
 3000-3499         (data packet dropped)
 3500-3999         3500-3999                           1000, SACK=3500-4000
 1000-1499         (data packet dropped)
 1500-2999         1500-1999                           1000, SACK=1500-2000, 3500-4000
                              2000-2499                           1000, SACK=2000-2500, 1500-2000, 3500-4000
                              1500-2999                           1000, SACK=1500-2000, 1500-3000, 3500-4000

可以看出最后一个SACK的第一个块是一个D-SACK,它包含的范围是1500-2000,而不是1500-2500。

在D-SACK使用了SACK同样的工作过程,它只是SACK的一个协议扩展。当使用D-SACK时,选项中的第一个字段的含义是“重复收到的报文段的序号”。其规则:

  • length后的第一个block(也就是第一个4字节)将包含重复收到的报文段的序号。
  • 如果D-SACK报告的报文段的序号在累积确认的报文段之后(并且不是期望收到的报文段,因为这是SACK工作的基础,也是D-SACK的基础),则在这个SACK选项中跟在D-SACK之后的第一个非D-SACK块将按照SACK的格式描述该报文段(被D-SACK确认的报文段,但是它所报告的可能比D-SACK报告的大,比如例子中的最后一个S-ACK)
  • 跟在D-SACK之后的SACK将按照SACK的方式工作。
  • 如果有多个被重复接收的报文段,则D-SACK只包含其中第一个。

如果收到了D-SACK,就表明接收方接收到了重复的报文段,这可能意味着网络中出现了复制或者是发送方过早重传了,或者是ACK丢失导致了不必要的重传。

4.发送方对SACK的响应

TCP的发送方(实际上也就是连接的双方,因为TCP是全双工的)需要维护一个未被确认的重传报文段队列,报文段未被确认前是不能释放的。重传送队列中的每个报文段都有一个标志位“SACKed”标识该报文段是否被SACK过,对于已经被SACK过的块,在重传时将被跳过。
发送方根据接收到的SACK的信息设置重传队列中的报文段的sacked标记。
当支持D-SACK时,发送方通过如下方式来判断是一个SACK还是一个D-SACK:

    • 如果SACK中的第一个block指定的序列号小于被累积确认的最后一个序列号,则是一个D-SACK
    • 如果SACK中的第一个block指定的序列号落在了其后的block描述的某个范围之内(因为SACK的格式是用两个值描述一个报文段的序号范围),则就是一个D-SACK。

转载于:https://www.cnblogs.com/tunian/p/9455381.html


推荐阅读
  • Final关键字的含义及用法详解
    本文详细介绍了Java中final关键字的含义和用法。final关键字可以修饰非抽象类、非抽象类成员方法和变量。final类不能被继承,final类中的方法默认是final的。final方法不能被子类的方法覆盖,但可以被继承。final成员变量表示常量,只能被赋值一次,赋值后值不再改变。文章还讨论了final类和final方法的应用场景,以及使用final方法的两个原因:锁定方法防止修改和提高执行效率。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • 本文介绍了九度OnlineJudge中的1002题目“Grading”的解决方法。该题目要求设计一个公平的评分过程,将每个考题分配给3个独立的专家,如果他们的评分不一致,则需要请一位裁判做出最终决定。文章详细描述了评分规则,并给出了解决该问题的程序。 ... [详细]
  • 禁止程序接收鼠标事件的工具_VNC Viewer for Mac(远程桌面工具)免费版
    VNCViewerforMac是一款运行在Mac平台上的远程桌面工具,vncviewermac版可以帮助您使用Mac的键盘和鼠标来控制远程计算机,操作简 ... [详细]
  • 原文地址:https:www.cnblogs.combaoyipSpringBoot_YML.html1.在springboot中,有两种配置文件,一种 ... [详细]
  • Google Play推出全新的应用内评价API,帮助开发者获取更多优质用户反馈。用户每天在Google Play上发表数百万条评论,这有助于开发者了解用户喜好和改进需求。开发者可以选择在适当的时间请求用户撰写评论,以获得全面而有用的反馈。全新应用内评价功能让用户无需返回应用详情页面即可发表评论,提升用户体验。 ... [详细]
  • Tomcat/Jetty为何选择扩展线程池而不是使用JDK原生线程池?
    本文探讨了Tomcat和Jetty选择扩展线程池而不是使用JDK原生线程池的原因。通过比较IO密集型任务和CPU密集型任务的特点,解释了为何Tomcat和Jetty需要扩展线程池来提高并发度和任务处理速度。同时,介绍了JDK原生线程池的工作流程。 ... [详细]
  • 本文介绍了Linux系统中正则表达式的基础知识,包括正则表达式的简介、字符分类、普通字符和元字符的区别,以及在学习过程中需要注意的事项。同时提醒读者要注意正则表达式与通配符的区别,并给出了使用正则表达式时的一些建议。本文适合初学者了解Linux系统中的正则表达式,并提供了学习的参考资料。 ... [详细]
  • 热血合击脚本辅助工具及随机数生成器源码分享
    本文分享了一个热血合击脚本辅助工具及随机数生成器源码。游戏脚本能够实现类似真实玩家的操作,但信息量有限且操作不可控。热血合击脚本辅助工具可以帮助玩家自动刷图、换图拉怪等操作,并提供了雷电云手机的扩展服务。此外,还介绍了使用mt_rand函数作为随机数生成器的代码示例。 ... [详细]
  • 闭包一直是Java社区中争论不断的话题,很多语言都支持闭包这个语言特性,闭包定义了一个依赖于外部环境的自由变量的函数,这个函数能够访问外部环境的变量。本文以JavaScript的一个闭包为例,介绍了闭包的定义和特性。 ... [详细]
  • 本文介绍了在Windows环境下如何配置php+apache环境,包括下载php7和apache2.4、安装vc2015运行时环境、启动php7和apache2.4等步骤。希望对需要搭建php7环境的读者有一定的参考价值。摘要长度为169字。 ... [详细]
  • flowable工作流 流程变量_信也科技工作流平台的技术实践
    1背景随着公司业务发展及内部业务流程诉求的增长,目前信息化系统不能够很好满足期望,主要体现如下:目前OA流程引擎无法满足企业特定业务流程需求,且移动端体 ... [详细]
  • Linux如何安装Mongodb的详细步骤和注意事项
    本文介绍了Linux如何安装Mongodb的详细步骤和注意事项,同时介绍了Mongodb的特点和优势。Mongodb是一个开源的数据库,适用于各种规模的企业和各类应用程序。它具有灵活的数据模式和高性能的数据读写操作,能够提高企业的敏捷性和可扩展性。文章还提供了Mongodb的下载安装包地址。 ... [详细]
  • 本文介绍了Linux Shell中括号和整数扩展的使用方法,包括命令组、命令替换、初始化数组以及算术表达式和逻辑判断的相关内容。括号中的命令将会在新开的子shell中顺序执行,括号中的变量不能被脚本余下的部分使用。命令替换可以用于将命令的标准输出作为另一个命令的输入。括号中的运算符和表达式符合C语言运算规则,可以用在整数扩展中进行算术计算和逻辑判断。 ... [详细]
author-avatar
蜗牛的家
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有