窗口到底有多滑动?揭秘TCP/IP滑动窗口的工作原理
本文分享自华为云社区《窗口到底有多滑动?揭秘TCP/IP滑动窗口的工作原理》,作者: Lion Long。
一、TCP报头
0 |1 |2 |3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-------------------------------+-------------------------------+
| Source Port | Destination Port |
+---------------------------------------------------------------+
| Sequence Number |
+---------------------------------------------------------------+
| Acknowledgment Number |
+-------+-----------+-+-+-+-+-+-+-------------------------------+
| Header| Reserve |U|A|P|R|S|F| |
| Length| |R|C|S|S|Y|I| Window size |
| | |G|K|H|T|N|N| |
+-------------------------------+-------------------------------+
| Checksum | Urgent Pointer |
+---------------------------------------------------------------+
| Option |
+---------------------------------------------------------------+
| Data |
| ... |
+---------------------------------------------------------------+
二、TCP流量控制
一般来说,我们希望数据传输得更快;但如果发送方发送数据过快,接收方还没来得急接收数据,就会造成丢包现象。
流量控制就是让发送方控制发送速率,让接收方能及时接收数据。TCP利用滑动窗口机制实现发送方的流量控制。
网络上进行数据传输的时候,需要考虑如何达到高效的收发数据。那么就需要考虑接收方可以接收多少网络包和网络上可以发送多少网络包的问题。
接收方通过发送数据出去的时候,同时告诉发送方我还能接收多少数据包。
要知道网络上数据传输的状态,可以通过计算往返时间。
2.1、持续计时器
TCP为每一个连接设有一个持续计时器。只有TCP的一方收到对方的零窗口通知,就启动持续计时器;只要持续计时器超时,就放送一个零窗口探测报文,携带一字节的数据;而对方收到零窗口探测报文时,回复自己现有的接收窗口值。如果窗口大小依旧是零,那么收到报文的一方就重新启动持续计时器。

零窗口探测报文丢失是不是无法打破死锁?零窗口探测报文发送的时候也会启动重传计时器,不必担心零窗口探测报文丢失会无法打破死锁局面。
持续计时器是为了解决双方相互等待(A等待B发送非零窗口的通知,B等待A发送数据)而形成的死锁现象。这种现象一般发生在发送窗口大小数据包丢失时。
2.2、RTT
RTT,全称Round Trip Time,即往返时间。由链路传播时间、末端系统处理时间、路由器缓存中排队和处理的时间组成。

Round Trip Time
对于TCP来说,路由器缓存中排队和处理的时间会随着网络拥塞程度辩护而变化。通过计算RTT可以反应网络拥塞程度,从而拥塞控制。

RTT
RTT的计算公式:new_RTT = percent*pre_RTT+(1-percent)*RTT;
其中percent取值范围0.8~0.9 ;pre_RTT是上一次的RTT,RTT是本次RTT。计算出来new_RTT,如果RTT大于new_RTT,那么就超时。
2.3、RTO
RTO,全称Retransmission TimeOut,即重传超时时间。
超时之后TCP进入Loss状态,重传所有没有被确认的报文,同时进入慢启动的回复过程。
2.4、拥塞的定义
随着网络上的主机不断增加其发送速率,会使整个网络变得非常拥挤;这会导致网络经常出现丢包现象,使网络传输效率大幅度下降。
如果不对网络做拥塞控制,会降低整个网络的传输效率,直到吞吐量为0,进入死锁。

拥塞
2.5、慢启动和拥塞控制
(1)一条TCP连接开始时,window size被设置为1 MSS(最大报文段大小)。
(2)TCP发送方发送完发送窗口数据,并收到所有的确认,window size以指数增长(以2的倍数进行翻倍),即慢启动阶段。
(3)window size增长到一个慢启动的阈值thresh,开始执行拥塞控制算法(window size呈线性增长),进入拥塞控制阶段。
(4)随着window size增长,发送速率提高,出现网络拥塞,分组超时重传。

慢启动

拥塞控制
慢启动是指一开始向网络中发送的报文段少,而不是指拥塞窗口增长速度慢。
拥塞避免不是指完全能够避免拥塞,而是指在拥塞避免阶段将拥塞窗口控制为线性规律增长,使网络比较不容易出现拥塞。
2.6、快重传和快恢复
1990增加新的拥塞控制算法:快重传和快恢复。用于改进TCP的性能。
有时候,个别报文会在网络中丢失,当实际上网络并没有发生拥塞,这将导致发送方超时重传并认为网络出现了拥塞;从而错误的启动慢启动算法,因此降低传输效率。为此,引入快重传算法,可以让发送方尽早知道个别报文段的丢失。
所谓快重传,就是发送方尽快的进行重传,而不是等超时计时器超时才重传。快重传可以使整个网络吞吐量提高约20%。

发送方接收到3个重复确认,就知道只丢失了个别报文段,于是不启动慢启动算法,而是执行快恢复算法。
所谓快恢复,就是发送方将慢启动上限和拥塞窗口值调整为当前窗口的一半,开始执行拥塞避免算法。
三、滑动窗口
TCP基于以字节为单位的滑动窗口来实现可靠传输。
滑动窗口需要考虑网络上能发多少以及接收方能接收多少;即窗口大小=min{接收方窗口,网络上可发送数据包大小};
两个指针,前指针指示已接收或已发送并确认的字节序,后指针指示不允许接收/发送的开始位置,两个指针之间就是可收发数据的窗口大小。
|<---------- window size ---------->|
+--------------+-----------------------------------+-------------+
|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|17|18|19|20|21 |
+--------------+--------------------+--------------+-------------+
|已发送并确认 P1 已发送未确认 P2 未发送 P3 不可接收 |
+----------------------------------------------------------------+
窗口大小是动态的,可以通过RTT计算。比如发4K到网络,出现拥塞,那么就将窗口逐渐减小。RTT防抖,可以推算窗口大小。
四、思考
(1)接收方不recv,发送方一直send,send的数据去哪里了??
这种情况接收方的缓冲区逐渐饱和,达到饱和时滑动窗口为0,此时发送方还在send,那么数据就会滞留在发送方的缓冲区,发送方缓冲区也会逐渐饱和,当发送方缓冲区无法再写入数据时,send返回-1,告诉应用程序IO不可写。
(2)tcp如何保证顺序?
不能保证接收序号是顺序的,只能保证应用程序取的时候是顺序的。适当延迟回复ACK可以提高TCP的传输效率,一般最多延迟0.5秒,否则可能会使重传计时器超时出现重传。
总结
- TCP通过以字节为单位的滑动窗口实现可靠传输。
- TCP进行流量控制时使用四个算法:慢启动、拥塞避免、快重传、快恢复。
- 滑动窗口是动态的,它的大小取接收端可接受窗口大小和网络可发送大小的最小值。比如一条公共路段和接收方的仓库,发送的货物多少取决于公路和仓库的最小值;公路很大但仓库很小,公路上运输再多的货物而仓库无法装载得下;仓库很大但公路较小,仓库就算能装再多的货物而公路只能运输少量的货物。
- 滑动窗口为0时,会开启持续计时器,用于探测接收方是否有空间接收数据,防止进入无休止的等待,即死锁。
- 详细的计算机网络知识,可以参看湖科大计算机网络视频。
窗口到底有多滑动?揭秘TCP/IP滑动窗口的工作原理的更多相关文章
- 转:TCP/IP协议栈的基本工作原理
转载自:http://jasonccie.blog.51cto.com/2143955/422966 TCP/IP是互联网的核心协议,也是大多数网络应用的核心协议.就前面一段时间面试中问到的TCP/I ...
- Spring Boot 揭秘与实战 源码分析 - 工作原理剖析
文章目录 1. EnableAutoConfiguration 帮助我们做了什么 2. 配置参数类 – FreeMarkerProperties 3. 自动配置类 – FreeMarkerAutoCo ...
- TCP/IP滑动窗口
T C P使用一种窗口(w i n d o w)机制来控制数据流.当一个连接建立时,连接的每一端分配一个缓冲区来保存输入的数据,并将缓冲区的尺寸发送给另一端.当数据到达时,接收方发送确认,其中包含了自 ...
- [TCP/IP] 滑动窗口
什么是滑动窗口? 滑动窗口机制是TCP协议的一种流量控制和防拥塞的机制. 滑动窗口的工作原理? 简单来讲,就是接收方和发送方分别保留一块缓冲区,作为接收和发送数据来使用,发送数据过程中,如果发送方发的 ...
- [心平气和读经典]The TCP/IP Guide(000)
The TCP/IP Guide [Page 39] The TCP/IP Guide: Introduction and "Guide to The Guide" | 第1章 概 ...
- 简单谈谈 TCP/IP
1.前言 IP 或 ICMP.TCP 或 UDP.TELNET 或 FTP.以及 HTTP 等都属于 TCP/IP 协议. 他们与 TCP 或 IP 的关系紧密,是互联网必不可少的组成部分.TCP/I ...
- TCP/IP详细解释--TCP/IP可靠的原则 推拉窗 拥塞窗口
TCP和UDP在同一水平---传输层.但TCP和UDP最不一样的地方.TCP它提供了一个可靠的数据传输服务,TCP是面向连接的,那.使用TCP两台主机通过第一通信"拨打电话"这个过 ...
- TCP/IP具体解释--TCP/IP可靠的原理 滑动窗体 拥塞窗体
TCP和UDP处在同一层---运输层,可是TCP和UDP最不同的地方是,TCP提供了一种可靠的数据传输服务,TCP是面向连接的,也就是说,利用TCP通信的两台主机首先要经历一个"拨打电话&q ...
- 计算机网络知识之TCP/IP协议簇
OSI参考模型 OSI的来源 OSI(Open System Interconnect),即开放式系统互联. 一般都叫OSI参考模型,是ISO(国际标准化组织)组织在1985年研究的网 ...
- TCP/IP详解 (转)
TCP/IP详解学习笔记(1)-基本概念 为什么会有TCP/IP协议 在世界上各地,各种各样的电脑运行着各自不同的操作系统为大家服务,这些电脑在表达同一种信息的时候所使用的方法是千差万别.就好像圣经中 ...
随机推荐
- springcloud/springboot集成NACOS 做注册和配置中心以及nacos源码分析
一.SpringCloud 简介 Spring Cloud 是一系列框架的有序集合如服务发现注册.配置中心.消息总线.负载均衡.熔断器.数据监控等. SpringCloud 将多个服务框架组合起来,通 ...
- html-0
选择器 (一):first-child和:first-of-type :first-child第一个元素 <!DOCTYPE html> <html> <head> ...
- 手撕Vuex-提取模块信息
前言 在上一篇[手撕Vuex-模块化共享数据]文章中,已经了解了模块化,与共享数据的注意点. 那么接下来就要在我们自己的 Nuex 中实现共享数据模块化的功能.那么怎么在我们自己的 Nuex 中实现共 ...
- P2360 地下城主
题目大意 背景是逃离\(3D\)地下监狱,也就是三维样例,你可以前往所在小格的前方,后方,左方,右方,上层,下层的小格,'.'表示可走,'x'表示墙壁,'S'表示起点,'E'表示终点.每走一小格花费一 ...
- 【主流技术】详解 Spring Boot 2.7.x 集成 ElasticSearch7.x 全过程(二)
目录 前言 一.添加依赖 二. yml 配置 三.注入依赖 四.CRUD 常用 API ES 实体类 documents 操作 常见条件查询(重点) 分页查询 排序 构造查询 测试调用 五.文章小结 ...
- 七天.NET 8操作SQLite入门到实战 - 第三天SQLite快速入门
前言 今天我们花费一个小时快速了解SQLite数据类型.SQLite常用命令和语法. 七天.NET 8操作SQLite入门到实战详细教程 第一天 SQLite 简介 第二天 在 Windows 上配置 ...
- GPTs 初体验 - 1 分钟就能创建一个自己的 ChatGPT?
就在 11.10 号早上,ChatGPT 已经偷摸的把GPTs功能,开放给所有尊贵的 Plus 用户了. 随着这波的功能开放,界面也是改了不少.点击左侧的 Explore 或者左下角的用户处,就可以直 ...
- Modbus转Profinet 网关
产品简介 实现 PROFINET 网络与串口网络之间的数据通信,三个串口可分别连接具有 RS232 或 RS485 接口的设 备到 PROFINET 网络.即将串口设备转换为 PROFINET 设备. ...
- 【python】Tkinter学习
定义 python自带的可编辑的GUI界面,是一个图像窗口. Tkinter是使用python进行窗口视窗设计的模块. 标签-按钮 2.1.Lable&Button标签和按钮 定义window ...
- 【Java】Java中StringBuilder()成员方法append()和toString()
StringBuilder就相当于C++的String长度可变,用于构造字符串对象,内部使用自动扩容的数组操作字符串数据. StringBuilder和StringBuffer使用的是相同的API[区 ...