当前位置: 首页 > news >正文

tcp滑动窗口原理

18.1 滑动窗口

我们再来看这个比喻:
在这里插入图片描述

网络仅仅是保证了整个网络的连通性,我们我们基于整个网络去传输,那么是不是我想发送多少数据就发送多少数据呢?如果是这样的话,是不是就会像我们的从一个池塘抽水去灌到另外一个池塘一样,想抽多少水就抽多少水,这是肯定不行的,因为我们不能让接收水的池塘溢出水了。那么在TCP协议中是如何控制的?

对于每一个socket,都有一个接收缓存,和发送缓存,对于接收端来讲,我们必须确保这个接收缓存不能溢出,为了做到如此,那么接收端在回复ACK时,必须通告这个接收缓存的可用空间有多大,OK,我们来看看TCP协议。
在这里插入图片描述

TCP头里定义了这个窗口大小的值。是由接收端回复ACK时填充的。于是发送端就可以根据这个接收端的窗口大小来发送数据,而不会导致接收端处理不过来。好了,为了说明整个滑动窗口,我们来看看整个tcp协议控制的数据结构。
在这里插入图片描述

从上图我们可知:

  • 接收端LastByteRead指向了TCP缓冲区中读到的位置,NextByteExpected指向的地方是收到的连续包的最后一个位置,LastByteRcved指向的是收到的包的最后一个位置,我们可以看到中间有些数据还没有到达,所以有数据空白区。
  • 发送端的LastByteAcked指向了被接收端Ack过的位置(表示成功发送确认),LastByteSent表示发出去了,但还没有收到成功确认的Ack,LastByteWritten指向的是上层应用正在写的地方。
    于是:
  • 接收端在给发送端回ACK中会汇报自己的AdvertisedWindow = MaxRcvBuffer – LastByteRcvd – 1;
  • 而发送方会根据这个窗口来控制发送数据的大小,以保证接收方可以处理。

那接收端是如何控制发送端的发送呢?首先,我们来看这个AdvertisedWindow在发送端是如何控制的,首先看这个布局:
在这里插入图片描述

上图中分成了四个部分,分别是:(其中那个黑模型就是滑动窗口)

#1 已收到ack确认的数据。
#2 发还没收到ack的。
#3 在窗口中还没有发出的(接收方还有空间)。
#4 窗口以外的数据(接收方没空间)

既然说是滑动窗口,那这个窗口是如何调整的呢?且看下图:
在这里插入图片描述

下面我们来看一下整个控制流程:
在这里插入图片描述

Zero Window
上图,我们可以看到一个处理缓慢的Server(接收端)是怎么把Client(发送端)的TCP Sliding Window给降成0的。此时,你一定会问,如果Window变成0了,TCP会怎么样?是不是发送端就不发数据了?是的,发送端就不发数据了,你可以想像成“Window Closed”,那你一定还会问,如果发送端不发数据了,接收方一会儿Window size 可用了,怎么通知发送端呢?

解决这个问题,TCP使用了Zero Window Probe技术,缩写为ZWP,也就是说,发送端在窗口变成0后,会发ZWP的包给接收方,让接收方来ack他的Window尺寸,一般这个值会设置成3次,第次大约30-60秒(不同的实现可能会不一样)。如果3次过后还是0的话,有的TCP实现就会发RST把链接断了。

注意:只要有等待的地方都可能出现DDoS攻击,Zero Window也不例外,一些攻击者会在和HTTP建好链发完GET请求后,就把Window设置为0,然后服务端就只能等待进行ZWP,于是攻击者会并发大量的这样的请求,把服务器端的资源耗尽。

另外,Wireshark中,你可以使用tcp.analysis.zero_window来过滤包,然后使用右键菜单里的follow TCP stream,你可以看到ZeroWindowProbe及ZeroWindowProbeAck的包。

Silly Window Syndrome
在这里插入图片描述

Silly Window Syndrome翻译成中文就是“糊涂窗口综合症”。正如你上面看到的一样,如果我们的接收方太忙了,来不及取走Receive Windows里的数据,那么,就会导致发送方越来越小。到最后,如果接收方腾出几个字节并告诉发送方现在有几个字节的window,而我们的发送方会义无反顾地发送这几个字节。

要知道,我们的TCP+IP头有40个字节,为了几个字节,要达上这么大的开销,这太不经济了。

另外,你需要知道网络上有个MTU,对于以太网来说,MTU是1500字节,除去TCP+IP头的40个字节,真正的数据传输可以有1460,这就是所谓的MSS(Max Segment Size)注意,TCP的RFC定义这个MSS的默认值是536,这是因为 RFC 791里说了任何一个IP设备都得最少接收576尺寸的大小(实际上来说576是拨号的网络的MTU,而576减去IP头的20个字节就是536)。

如果你的网络包可以塞满MTU,那么你可以用满整个带宽,如果不能,那么你就会浪费带宽。(大于MTU的包有两种结局,一种是直接被丢了,另一种是会被重新分块打包发送) 你可以想像成一个MTU就相当于一个飞机的最多可以装的人,如果这飞机里满载的话,带宽最高,如果一个飞机只运一个人的话,无疑成本增加了,也而相当二。

所以,Silly Windows Syndrome这个现像就像是你本来可以坐200人的飞机里只做了一两个人。 要解决这个问题也不难,就是避免对小的window size做出响应,直到有足够大的window size再响应,这个思路可以同时实现在sender和receiver两端:

  • 如果这个问题是由Receiver端引起的,那么就会使用 David D Clark’s 方案。在receiver端,如果收到的数据导致window size小于某个值,可以直接ack(0)回sender,这样就把window给关闭了,也阻止了sender再发数据过来,等到receiver端处理了一些数据后windows size 大于等于了MSS,或者,receiver buffer有一半为空,就可以把window打开让send 发送数据过来。
  • 如果这个问题是由Sender端引起的,那么就会使用著名的 Nagle’s algorithm。这个算法的思路也是延时处理,他有两个主要的条件:1)要等到 Window Size>=MSS 或是 Data Size >=MSS,2)收到之前发送数据的ack回包,他才会发数据,否则就是在攒数据。

另外,Nagle算法默认是打开的,所以,对于一些需要小包场景的程序——比如像telnet或ssh这样的交互性比较强的程序,你需要关闭这个算法。你可以在Socket设置TCP_NODELAY选项来关闭这个算法(关闭Nagle算法没有全局参数,需要根据每个应用自己的特点来关闭)

	setsockopt(sock_fd, IPPROTO_TCP, TCP_NODELAY, (char \*)&value,sizeof(int));

另外,网上有些文章说TCP_CORK的socket option是也关闭Nagle算法,这不对。TCP_CORK其实是更新激进的Nagle算法,完全禁止小包发送,而Nagle算法没有禁止小包发送,只是禁止了大量的小包发送。最好不要两个选项都设置。

相关文章:

tcp滑动窗口原理

18.1 滑动窗口 我们再来看这个比喻: 网络仅仅是保证了整个网络的连通性,我们我们基于整个网络去传输,那么是不是我想发送多少数据就发送多少数据呢?如果是这样的话,是不是就会像我们的从一个池塘抽水去灌到另外一个…...

3.4 Android bpfloader初始化流程解读(二)

我继续看bpfloader是如何读取和处理bpf程序的。 4.2 读取代码段之readCodeSections static int readCodeSections(ifstream& elfFile, vector<codeSection>& cs, size_t sizeOfBpfProgDef,const bpf_prog_type* allowed, size_t numAllowed) {...ret = readSect…...

Linux0.12内核源码解读(2)-Bootsect.S

作者&#xff1a;小牛呼噜噜 | https://xiaoniuhululu.com 计算机内功、源码解析、科技故事、项目实战、面试八股等更多硬核文章&#xff0c;首发于公众号「小牛呼噜噜」 文章目录 回顾计算机启动过程8086、80x86是什么意思?寄存器初始化CS:IPCPU是如何和ROM相连的?加载MBR到…...

虚拟环境搭建、后台项目创建及目录调整、封装logger、封装全局异常、封装Response、后台数据库创建

1 虚拟环境搭建 #1 虚拟环境作用多个项目&#xff0c;自己有自己的环境&#xff0c;装的模块属于自己的# 2 使用pycharm创建-一般放在项目路径下&#xff1a;venv文件夹-lib文件夹---》site-package--》虚拟环境装的模块&#xff0c;都会放在这里-scripts--》python&#xff0…...

每日一练 | 网络工程师软考真题Day39

1、Windows Server 2003操作系统中&#xff0c;IIS6.0不提供以下 效劳。 A&#xff0e;web B&#xff0e;smtp C&#xff0e;pop3 D&#xff0e;ftp 2、Windows Server 2003操作系统中&#xff0c; 提供了远程桌面访问。 A&#xff0e;ftp B&#xff0e;email C&#xf…...

Android Studio编写xml布局不提示控件的部分属性问题的解决

最近突然发现Android Studio编写xml&#xff0c;发现有一部分控件的属性没有了代码提示&#xff0c;主要体现为id,margin等属性不再有代码提示&#xff0c;如下图。 但是手动输入仍然有效。然后删掉Android Sdk重新回来还是发现有问题&#xff0c;导一个之前的旧项目进来&#…...

BUGKU-simple_SSTI_1漏洞注入

SSTI漏洞注入 SSTI全称Server side template injection.服务端模板注入这节课主要讲flask的模板注入.flask会把类似于 的变量当做参数来渲染并填充到web页面,如果该参数可控并被后台解析则有可能被注入恶意代码导致注入漏洞请注意 模板注入只会存在于二次渲染中,无二次渲染不会…...

Python:dict

一些关于dict的奇妙观察 实验一 首先&#xff0c;创建两个一模一样的字典&#xff1a; dict1 {a: 1} dict2 {a: 1}然后&#xff0c;进行各种各样的相等判断&#xff1a; print(dict1 dict2) print(dict1.keys() dict2.keys()) print(dict1.values() dict2.values()) p…...

git和svn 的国内的下载地址

CNPM Binaries Mirror 下面是svn的地址 TortoiseSVN 64位下载-TortoiseSVN客户端官方版下载-华军软件园...

matplotlib制图进阶版

需求&#xff1a;两个产品销量的可视化折线图 1、使用pandas读取数据 2、生成销售数量的折线图...

【Java 进阶篇】HTML介绍与软件架构相关知识详解

HTML&#xff08;Hypertext Markup Language&#xff09;是一种用于创建网页的标记语言。它是互联网上信息传递和展示的基础&#xff0c;无论是在浏览器中查看网页还是在移动设备上浏览应用程序&#xff0c;HTML都扮演着关键角色。本文将向您介绍HTML的基础知识&#xff0c;并探…...

Python数据攻略-Pandas与机器学习数据准备

在机器学习项目中,大部分时间都花在了数据准备上。你可能听说过“数据是机器学习的燃料”的说法,这是因为高质量的数据是构建出色模型的关键。 在这篇文章中将使用Pandas库来进行数据准备。为了让内容更贴近实际将使用《三国志》游戏中的角色数据作为样本。 文章目录 数据编…...

阿里云/亚马逊云代理:aws账号购买:aws亚马逊云账号的优势

AWS 可以用多少付多少&#xff0c;无预付费用&#xff0c;无需签订长期使用合约。我们能够构建和管理大规模的全球基础设施&#xff0c;aws账号购买并以降低价格的形式将节约成本的优势传递给您。借助我们在规模和专业知识方面的效益&#xff0c;过去四年来&#xff0c;我们已在…...

JSON的MIME媒体类型是application/json

JSON&#xff08;全称 JavaScript Object Notation&#xff09;即JavaScript对象表示法&#xff0c;通知使用application/json媒体类型。 目录 1、JSON介绍 2、JSON语法 3、实践总结 运行环境&#xff1a; Windows-7-Ultimate-x64、Windows-10-BusinessEditions-21h2-x64 1…...

C++ 之如何将数组传递给函数?

在本文中&#xff0c;您将学习将数组传递给C 中的函数。您将学习如何传递一维和多维数组。 数组可以作为参数传递给函数。也可以从函数返回数组。考虑以下示例&#xff0c;将一维数组传递给函数&#xff1a; 示例1&#xff1a;将一维数组传递给函数 C 程序通过将一维数组传递…...

1.7 计算机网络体系结构

思维导图&#xff1a; 1.7.1 计算机网络的体系结构的形成 **1.7 计算机网络体系结构** 计算机网络体系结构中&#xff0c;分层的思想为核心。该方法使得复杂的网络设计变得更为简单和可管理。 **1.7.1 计算机网络体系结构的形成** - **计算机网络的复杂性**: 即使是简单的文…...

boost在不同平台下的编译(win、arm)

首先下载boost源码 下载完成之后解压 前提需要自行安装gcc等工具 window ./bootstrap.sh ./b2 ./b2 installarm &#xff08;linux&#xff09; sudo ./bootstrap.sh sudo ./b2 cxxflags-fPIC cflags-fPIC linkstatic -a threadingmulti sudo ./b2 installx86 (linux) su…...

计算机网络(第8版)第一章概述笔记

6 性能指标 带宽&#xff1a; 在单位时间内从网络中的某一点到另一点所能通过的“最高数据率”。 7 分层结构、协议、接口、服务 1、实体&#xff1a;第n层的活动元素称为n层实体。同一层的实体叫对等实体。 2、协议&#xff1a;为进行网络中的对等实体数据交换而建立的规则、…...

Linux 部署项目

部署 Linux 部署项目1. 宝塔部署1.1 前端部署1.2 后端部署 2. docker 部署2.1 后端部署2.2 前端部署 3. 跨域问题3.1 Nginx 代理&#xff08;推荐&#xff09;3.2 修改后端服务3.3 添加 web 全局请求拦截器 4. 域名解析DNSPod添加域名 Linux 部署项目 1. 宝塔部署 准备工作&am…...

MySQL 基础

MySQL 基础 顾名思义&#xff0c;关系型数据库&#xff08;RDB&#xff0c;Relational Database&#xff09;就是一种建立在关系模型的基础上的数据库。关系模型表明了数据库中所存储的数据之间的联系&#xff08;一对一、一对多、多对多&#xff09;。 关系型数据库中&#…...

Flask RESTful 示例

目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题&#xff1a; 下面创建一个简单的Flask RESTful API示例。首先&#xff0c;我们需要创建环境&#xff0c;安装必要的依赖&#xff0c;然后…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

MySQL账号权限管理指南:安全创建账户与精细授权技巧

在MySQL数据库管理中&#xff0c;合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号&#xff1f; 最小权限原则&#xf…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)

漏洞概览 漏洞名称&#xff1a;Apache Flink REST API 任意文件读取漏洞CVE编号&#xff1a;CVE-2020-17519CVSS评分&#xff1a;7.5影响版本&#xff1a;Apache Flink 1.11.0、1.11.1、1.11.2修复版本&#xff1a;≥ 1.11.3 或 ≥ 1.12.0漏洞类型&#xff1a;路径遍历&#x…...

IP如何挑?2025年海外专线IP如何购买?

你花了时间和预算买了IP&#xff0c;结果IP质量不佳&#xff0c;项目效率低下不说&#xff0c;还可能带来莫名的网络问题&#xff0c;是不是太闹心了&#xff1f;尤其是在面对海外专线IP时&#xff0c;到底怎么才能买到适合自己的呢&#xff1f;所以&#xff0c;挑IP绝对是个技…...

人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式

今天是关于AI如何在教学中增强学生的学习体验&#xff0c;我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育&#xff0c;这并非炒作&#xff0c;而是已经发生的巨大变革。教育机构和教育者不能忽视它&#xff0c;试图简单地禁止学生使…...

DingDing机器人群消息推送

文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人&#xff0c;点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置&#xff0c;详见说明文档 成功后&#xff0c;记录Webhook 2 API文档说明 点击设置说明 查看自…...

jmeter聚合报告中参数详解

sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample&#xff08;样本数&#xff09; 表示测试中发送的请求数量&#xff0c;即测试执行了多少次请求。 单位&#xff0c;以个或者次数表示。 示例&#xff1a;…...

Python 实现 Web 静态服务器(HTTP 协议)

目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1&#xff09;下载安装包2&#xff09;配置环境变量3&#xff09;安装镜像4&#xff09;node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1&#xff09;使用 http-server2&#xff09;详解 …...

Unity UGUI Button事件流程

场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...