TCP可靠传输及流量控制实现原理
一、为什么TCP是可靠传输?
1. 停止等待协议
- 通过确认与超时重传机制实现可靠传输
- 在发送完一个分组后,必须暂时保留已发送的分组的副本。
- 分组和确认分组都必须进行编号。
- 超时计时器的重传时间应当比数据在分组传输的平均往返时间更长一些。
出现差错或丢失的时候,发送方会将自己备份的副本再重传一次,直到收到接收的确认信息。当接收方收到重复的数据时,会直接丢弃,但是会给发送方请确认自己已经收到了。
2. 改进的停止等待协议——连续ARQ协议和滑动窗口协议
上面的停止等待协议每发送一组数据就必须等到接收方回复确认后,再发起第二组数据,如果出现超时重传的话,效率更低。因此为了提高传输的效率,改进了等待传输协议。
连续ARQ协议和滑动窗口协议的机制是以接收方回复确认为单位,每次连续发送一个滑动窗口指定的数据组。示例图如下:
2.1 什么是滑动窗口协议?(发送方怎么发送数据)
滑动窗口是由发送方维护的类似指针的变量,在每收到一个接收方的确认消息后,该指针向前移动并发送数据,到窗口指定大小的数据组时停下,等待接收方的确认。示意看图:
2.2 接收方怎么回复确认?
累积确认机制
发送方不对收到的分组逐个发送确认,而是对按序到达的最后一个分组发送确认,这样就表示:到这个分组为止的所有分组都已正确收到了。
优点:容易实现,即使确认丢失也不必重传。
缺点:不能向发送方反映出接收方已经正确收到的所有分组的信息。
Go-back-N(回退 N)
为了解决上述同一窗口中数据组不能完整确认的问题,连续ARQ协议采用了回退机制。比如说:发送方发送了前 5 个分组,而中间的第 3 个分组丢失了。这时接收方只能对前两个分组发出确认。发送方无法知道后面三个分组的下落,而只好把后面的三个分组都再重传一次。这就叫做 Go-back-N(回退 N),表示需要再退回来重传已发送过的 N 个分组。
结论:当通信线路质量不好时,连续 ARQ 协议会带来负面的影响。可能还不如传统的停止等待协议。
3. TCP可靠传输的实现
- TCP 连接的每一端都必须设有两个窗口——一个发送窗口和一个接收窗口。
- TCP 的可靠传输机制用字节的序号进行控制。TCP 所有的确认都是基于序号而不是基于报文段。
- TCP 两端的四个窗口经常处于动态变化之中。
- TCP连接的往返时间 RTT 也不是固定不变的。需要使用特定的算法估算较为合理的重传时间。
3.1 以字节为单位的滑动窗口技术
滑动窗口是面向字节流的,为了方便记住每个分组的序号,下面的图解以一个分组假设100个字节,为了方便画图表示,将分组进行编号简化表示,如图所示,但是要记住,每一个分组的序号是多少。
3.2 改进的确认——选择确认(SACK)
TCP通信时,如果发送序列中间某个数据包丢失,TCP会通过重传最后确认的分组后续的分组,这样原先已经正确传输的分组也可能重复发送,降低了TCP性能。SACK(Selective Acknowledgment,选择确认)技术,使TCP只重新发送丢失的包,不用发送后续所有的分组,而且提供相应机制使接收方能告诉发送方哪些数据丢失,哪些数据已经提前收到等。在建立 TCP 连接时,就要在 TCP 首部的选项中加上“允许 SACK”的选项,而双方必须都事先商定好。原来首部中的“确认号字段”的用法仍然不变。只是以后在 TCP 报文段的首部中都增加了 SACK 选项,以便报告收到的不连续的字节块的边界。
选择性确认最多表示4个边界:由于首部选项的长度最多只有 40 字节。需要一个字节指明是SACK选项,另一个字节指明占多少字节。而指明一个边界就要用掉 4 字节。在选项中最多只能指明 4 个字节块的边界信息。因4个字节块共8个边界信息。
抓包分析:
3.3 超时重传时间的选择
重传机制是 TCP 中最重要和最复杂的问题之一。TCP 每发送一个报文段,就对这个报文段设置一次计时器。只要计时器设置的重传时间到但还没有收到确认,就要重传这一报文段。那么这个重传时间到底应该设置多少呢?这里面有学问。以下是我截取的“手抄报”,暂时看不懂。建议跳过。
加权平均往返时间
TCP 保留了 RTT 的一个加权平均往返时间 RTTS(这又称为平滑的往返时间)。第一次测量到 RTT 样本时,RTTS 值就取为所测量到的 RTT 样本值。以后每测量到一个新的 RTT 样本,就按下式重新计算一次 RTTS:
超时计时器设置的超时重传时间RTO
往返时间的测量
Karn算法
二、TCP的流量控制
流量控制(flow control)就是让发送方的发送速率不要太快,既要让接收方来得及接收,也不要使网络发生拥塞。利用滑动窗口机制可以很方便地在 TCP 连接上实现流量控制。
流量控制举例说明:
零窗口处理——持续计数器
考虑上面的例子中,当A发送的数据已经到达B的接收窗口上限,此时A就必须等待B处理了部分数据后,待接收窗口有空闲的时候,再次发送数据,那么A是怎么知道B的接收窗口何时有空闲呢?这时就用到了持续计时器。
TCP 为每一个连接设有一个持续计时器。只要 TCP 连接的一方收到对方的零窗口通知,就启动持续计时器。若持续计时器设置的时间到期,就发送一个零窗口探测报文段(仅携带 1 字节的数据),而对方就在确认这个探测报文段时给出了现在的窗口值。若窗口仍然是零,则收到这个报文段的一方就重新设置持续计时器。若窗口不是零,则死锁的僵局就可以打破了。
三、TCP的传输效率
关于TCP的传输效率问题,需要从三方面来考虑,1.何时发送;2.少字节发送数据问题;3.糊涂窗口综合症问题
3.1 TCP报文的发送时机:
第一种机制是 TCP 维持一个变量,它等于最大报文段长度 MSS。只要缓存中存放的数据达到 MSS 字节时,就组装成一个 TCP 报文段发送出去。
第二种机制是由发送方的应用进程指明要求发送报文段,即 TCP 支持的推送(push)操作。
第三种机制是发送方的一个计时器期限到了,这时就把当前已有的缓存数据装入报文段(但长度不能超过 MSS)发送出去。
3.2 少量字节发送数据问题:
问题描述:如果应用程序一次产生一字节数据,这样会导致网络由于太多的包而过载。如:从键盘输入的一个字符,占用一个字节,可能在传输上造成41字节的包,其中包括1字节的有用信息和40字节的标题数据。
解决方案(NAGLE算法):发送端的应用进程将欲发送的数据逐个字节地送到TCP缓存,则发送端就将第一个字符先发送出去。将后面到达的字符都缓存起来。当接收端收到对第一个字符确认后,再将缓存中的所有字符装成一个报文段发送出去,同时继续对随后到在的字符进行缓存。只有在收到对前一个报文段确认后才继续发送下一个报文段。
3.3 糊涂窗口综合症问题:
问题描述:设想一种情况:接收端缓存已满,而交互式的应用进程一次只从缓存中读取一个字符,然后向发送端发送确认,并将窗口设置1个字节。接着发送端又发来1个字符。接收端发回确认,仍然将窗口设置为1个字节。这样下去,网络效率非常低。
解决方案:接收端等待一段时间,使得缓存已有足够空间容纳;或者缓存已有一半空的空间,再向发送端发送确认。
看了又看-——> TCP拥塞控制与连接管理(TCP连接3次握手,4次挥手)
TCP可靠传输及流量控制实现原理的更多相关文章
- TCP 可靠传输与流量控制的实现
TCP 可靠传输与流量控制的实现 一.TCP可靠传输的实现 现在所讲的可靠传输是根据之前所说的可靠传输原理的实现,是现实中应用的技术. 1.1.以字节为单位的滑动窗口 如图A端一份文件分为了多个字节, ...
- TCP可靠传输原理
停止等待协议 "停止等待"就是发送方在发送完一个分组后停止发送,等待接收方的确认后再继续发送. 超时重传 发送方在等待一定时间后如果还没有收到接收方的确认,此时发送方将认定分组没有 ...
- TCP可靠传输的工作原理
TCP可靠传输的工作原理 一.停止等待协议 1.1.简介 在发送完一个分组后,必须暂时保留已发送的分组的副本. 分组和确认分组都必须进行编号. 超时计时器的重传时间应当比数据在分组传输的平均往返时间更 ...
- 计算机网络概述 传输层 TCP可靠传输的实现
TCP可靠传输的实现 TCP的可靠性表现在:它向应用层提供的数据是 无差错的.有序的.无丢失的,简单的说就是:TCP最终递交给应用层的数据和发送者发送的数据是一模一样的. TCP采用了流量控制.拥塞控 ...
- 运输层6——TCP可靠传输的实现
目录 1. 以字节为单位的滑动窗口 2. 超时重传时间的选择 写在前面:本文章是针对<计算机网络第七版>的学习笔记 运输层1--运输层协议概述 运输层2--用户数据报协议UDP 运输层3- ...
- TCP可靠传输
1. TCP 可靠性如何保证? 信道可靠:用三次握手.四次挥手保证连接正确: 数据正确:分区编号.校验和.超时重传: 传输控制:流量控制.拥塞控制 2. 重传机制 TCP可靠传输方式是序列号与确认应答 ...
- TCP可靠传输的实现
TCP可靠传输的实现 1.概述 为方便描述可靠传输原理,假定数据传输只在一个方向上进行,即A发送数据,B给出确认 2.以字节为单位的滑动窗口 TCP的滑动窗口是以字节为单位的.为了 ...
- 计算机网络(9)-----TCP可靠传输的实现
TCP可靠传输的实现 以字节为单位的滑动窗口 滑动窗口的滑动是以字节为单位的,发送方A和接收方B在TCP三次握手的前两次握手时协商好了发送窗口和接受窗口的大小,发送方A根据B发送来的确认连接报文中标明 ...
- 计算机网络传输层之TCP可靠传输
文章转自:https://blog.csdn.net/weixin_43914604/article/details/105524592 学习课程:<2019王道考研计算机网络> 学习目的 ...
随机推荐
- Java并发编程原理与实战二十四:简易数据库连接池
public class MyDataSource { private static LinkedList<Connection> pool = new LinkedList<> ...
- 纯javascript代码实现浏览器图片选择预览、旋转、批量上传
工作中遇到的业务场景,和同事一起研究了下,主要是为了兼容IE版本 其实就是一些琐碎的知识点在网上搜集下解决方式,然后集成了下,主要有以下点: 1. IE input type=file的图片预览要用I ...
- Struts S2-052漏洞利用之Meterpreter(CVE-2017-9805)
Struts S2-052漏洞爆出来已经快一周了,大家可能更想知道其危害~鸡肋? 这里就直接给出漏洞利用拿Meterpreter的过程,想了解更多的请参考其他文章,下面是实验演示部分.Struts S ...
- Django框架下的小人物--Cookie
1. 什么是Cookie,它的用途是什么? Cookies是一些存储在用户电脑上的小文件.它是被设计用来保存一些站点的用户数据,这样能够让服务器为这样的用户定制内容,后者页面代码能够获取到Cookie ...
- Inline函数使用注意事项
Inline函数使用注意事项 1.在一个文件中定义的inline函数不能再另一个文件中使用 2.inline函数应简洁,只有少数几个语句. 3.在inline函数中不能有循环,if,switch语句. ...
- oracle 修改属性
alter table 表名 modify 字段名 类型; alter table 表名 modify 字段名 属性名; alter table TEST modify sbirthday not n ...
- jQuery学习(二) 自定义扩展函数
jQuery函数调用写法很优雅,在项目开发过程中,有需要自定义函数经常被使用到,将这些函数放置到项目ExtTool.js中,为了编码方式的统一,也希望这些自定义函数与jQuery函数一致的调用方式.在 ...
- C 语言问题
1. 如何生成 "半全局变量", 就是那种只能被部分源文件中的部分函数访问变量? 答: 这在C语言中办不到. 如果不能或不方便在一个源文件中放下所有的函数, 那么有三种的解决方案 ...
- 二、springboot配置
一.启动类 在包根目录下添加启动类,必须包含main方法,再添加Spring Boot启动方法: SpringApplication.run(SampleController.class, args) ...
- js自定义鼠标右键菜单
document.oncontextmenu = function(e) { return false; } document.onmousedown = function(e) { switch(e ...