窗口到底有多滑动?揭秘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协议 在世界上各地,各种各样的电脑运行着各自不同的操作系统为大家服务,这些电脑在表达同一种信息的时候所使用的方法是千差万别.就好像圣经中 ...
随机推荐
- Jenkins-插件安装-多实例
1,Jenkins插件安装: Jenkins最大的功能莫过于插件丰富,基于各种插件可以满足各项需求,Jenkins本身是一个框架,真正发挥作用的各种插件.Jenkins默认自带很多插件,如果没有添加新 ...
- shell- ssh免密登录脚本
#!/bin/sh . /etc/init.d/functions #1.product key pair /usr/bin/rm -f .ssh/* 2&>/dev/null [ -f ...
- fread实现getchar(加速!!!)
fread实现的getchar代码: inline char get() { static char buf[100000], *p1 = buf, *p2 = buf; return p1 == p ...
- CF1333A [Little Artem]
Problem 题目简述 给你一个 \(n \times m\) 的方格,构造一个方案,使得方案中 \(B = W + 1\). \(B\):相邻的格子有至少一个白色格子的黑色格子的个数. \(W\) ...
- sql删除进程
使用一下语句杀掉进程 USE master go DECLARE @dbname VARCHAR(200) SET @dbname = 'xxxx' --要关闭进程的数据库名 DECLARE @sql ...
- Python JSON 使用指南:解析和转换数据
JSON 是一种用于存储和交换数据的语法.JSON 是文本,使用 JavaScript 对象表示法编写. Python 中的 JSON Python 有一个内置的 json 包,可用于处理 JSON ...
- Qt源码解析——元对象系统热身
关键词:Qt 源码 QObject QMetaObject 元对象系统 属性 事件 信号 槽 概述 原系列文章地址 官方文档第二章内容就是元对象系统,它在介绍里描述到: Qt的元对象系统提供了信号和槽 ...
- 16个值得推荐的.NET ORM框架(含使用情况统计的投票,欢迎参与)
什么是ORM? ORM 是 Object Relational Mapping 的缩写,译为"对象关系映射",是一种程序设计技术,用于实现面向对象编程语言里不同类型系统的数据之间的 ...
- [ABC262D] I Hate Non-integer Number
Problem Statement You are given a sequence of positive integers $A=(a_1,\ldots,a_N)$ of length $N$. ...
- C++ Qt开发:ProgressBar进度条组件
Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍Progres ...