《TCP/IP详解 卷一》第15章 TCP数据流与窗口管理
目录
15.1 引言
15.2 交互式通信
15.3 延时确认
15.4 Nagle 算法
15.4.1 延时ACK与Nagle算法结合
15.4.2 禁用Nagle算法
15.5 流量控制与窗口管理
15.5.1 滑动窗口
15.5.2 零窗口与TCP持续计时器
15.5.3 糊涂窗口综合征
15.5.4 大容量缓存与自动调优
15.6 紧急机制
15.7与窗口管理相关的攻击
15.8总结
15.1 引言
两类TCP传输:
交互式传输:
单个报文小,如ssh,网络游戏中账号信息,鼠标操作等信息。
批量传输:
即大量数据传输。如文件共享下载,web访问。
需流量控制,防止接收端溢出。
15.2 交互式通信
网络中大部分是大批量传输,少部分是交互式传输。
ssh是典型交互式数据。
特点:小包。
ssh每个输入一个字符会生成4个TCP数据段:
1. 客户端指令输入
2. 服务器ACK
3. 服务器执行结果
4. 客户端ACK
其中2,3可合并一起发送,即ACK报文携带回显数据,这叫延迟ACK。
TCP段PSH标志含义:
表示发送端没有其他数据需要传输。而接收端收到数据后应立即传递给应用层。
因为SSH客户端产生的都是短小信息,通常SSH TCP报文都带PSH标志。
15.3 延时确认
延迟ACK:
TCP不会对收到的每个数据都回复一个ACK,而是通过累积ACK后将延迟的ACK和后续需要传的数据结合发送。
常用于批量数据传输中。
好处:减少ACK数目,减轻网络负载。
而快速ACK,即每个报文都会回复一个ACK。
15.4 Nagle 算法
SSH客户端一个单击动作会产生四个TCP报文,其中包含TCP头,IP头等开销,代价很高,会加重广域网阻塞。
解决方法:Nagle算法
Nagle翻译:突然
Nagle原理:
若发送端没有收到所有数据的ACK时,不发送小报文。直到所有在传数据收到ACK,在这个等待期间会整合多个小数据,通过一个更大报文发送。
所以ACK返回越快,数据发送越快。
优点:在高延迟网络中可整合小数据,减少小包数目。
缺点:增加了时延。
Nagle算法适用场景:
频繁传输小数据块,并延迟不敏感。
15.4.1 延时ACK与Nagle算法结合
延时ACK:延迟发送ACK,用于减少ACK包的数量,降低网络开销。
Nagle算法:等待收到所有已发送数据的ACK后,期间合并小包成大包再发送数据。
所以可知,两者结合使用导致短暂死锁。
所以如果SSH服务器开启了延迟ACK功能,客户端最好禁用Nagle。
15.4.2 禁用Nagle算法
Nagle算法增加了时延,对实时应用不适合。
如SSH,实时网络游戏。
内核协议栈禁用Nagle:
net.ipv4.tcp_no_delay = 1
应用程序禁用:
设置socket TCP_NODELAY选项
setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (void *)&flag, sizeof(int))
15.5 流量控制与窗口管理
每个TCP报文段包含:序列号,ACK号,窗口大小。
ACK号:下一次期待收到的报文序列号,说明之前的数据已全部接收。
窗口大小:向对方指示,自己的接收缓冲区还剩多少空间。
15.5.1 滑动窗口
每对TCP连接的两端都维护一个发送窗口和接收窗口。
其中发送窗口大小由对端的接收窗口通告。
在没收到数据的ACK情况下,最多可发送的数据量就是发送窗口大小。
滑动窗口作用:
优化网络利用率:
滑动窗口允许发送方连续发送多个数据段而不必等待每个数据段ACK。提高网络利用率。
避免拥塞:
发送方根据接收方通告的窗口大小来控制发送量,避免发送过快而引起拥塞。
发送窗口:

一旦收到已发送数据的ACK后,就移动窗口,可继续发送更多数据。
接收窗口:

把接收窗口值给通告给发送方。
收到数据的序列号小于左边界RCV.NXT,就是重复报文,丢弃数据。
收到数据的序列号大于右左边界RCV.NXT+RCV.WND,超出处理范围,丢弃数据。
15.5.2 零窗口与TCP持续计时器
TCP通过接收端的窗口通告实现流量控制。指示接收端缓冲区可接收数量。
通告的接收窗口为0时,可阻止对方发送。
接收端缓冲区重新有可用空间时,可传输一个窗口更新给发送端。该窗口更新是一个纯ACK,不包含数据。
问题:
如果接收端的窗口更新报文丢失,而发送方需要等到窗口更新报文才可继续发送。造成死锁。
解决方法:
周期向接收端查询窗口值,即发送窗口探测,接收端回复一个ACK报文,其中包含窗口大小。
TCP报文是纯ACK,则不会重传ACK。
TCP报文不是纯ACK,会重传ACK和数据。
15.5.3 糊涂窗口综合征
糊涂窗口综合征SWS
出现原因有:
接收端没等到窗口变大就通告,导致通告的窗口小。
发送端没等到将小数据合成更大报文就方法,导致发送数据小。
坏处:
传输的TCP数据很小。传输效率低。
解决方法:
接收端不通告小窗口值。
发送端不发送小报文段,由Nagle控制如何发送。
15.5.4 大容量缓存与自动调优
不必提前设置一个过大发送/接收缓存。而是根据待传数据大小,不断估算缓存大小,不断通告窗口大小。
即窗口自动调优。
如何设置窗口的自动调优范围:
接收窗口:
net.ipv4.tcp_rmem= 4096 87380 174760
发送窗口:
net.ipv4.tcp_wmem= 4096 87380 174760
上述三个值分别是最小值,默认值,最大值。
最小值:
应用程序设置发送缓冲区小于最小值时,内核自动扩大到最小值,如4096。
默认值:
应用程序未指定发送缓冲区大小时,内核会使用这个默认值。
最大值:
应用程序不能设置发送缓冲区的大小超过最大值。
自动调优:
当接收端根据接收缓存区剩余大小,动态发送窗口更新报文给发送端,控制发送端发送速率。
若TCP的接收缓存区太小,会严重限制TCP吞吐量。
小结:接收窗口和发送窗口值会根据网络环境和系统配置而动态调整,通常范围为几KB到几MB。
15.6 紧急机制
TCP URG标志:
指示该TCP报文包含紧急数据。
MSG_OOB标志可发送接收带外数据。
带外数据:使用带外(额外)通道来传输数据,可不受滑动窗口控制,实现传输紧急数据。
MSG_OOB使用方法如:
send(socket_fd, buff, buff_len, MSG_OOB);
recv(socket_fd, buffer, MAX_BUFFER_SIZE, MSG_OOB);
MSG_OOB数据比普通数据有更高优先级。
15.7与窗口管理相关的攻击
通告非常小的窗口,让发送方缓慢发送,并保持忙碌发送,耗尽资源。
15.8总结
延迟ACK:
使用场景:交互式通信中,当接收方收到数据后,延迟回复ACK,等到有数据发送时再一起携带ACK发送。
优点:减少包数量。
缺点:延时增大。
Nagle算法:
使用场景:广域网中RTT较大的环境中,采用Nagle算法,可以合并多个小数据包成一个,再发送。
优点:减少包数量,降低传输开销。
缺点:延时增大。
延迟ACK和Nagle算法会短暂死锁,有的会禁用Nagle算法。
通常延时不敏感的交互式应用可使用Nagle。
当接收端的接收缓存为空,会通告窗口为0。此时发送端会停止发送,并周期发送窗口探测,直到通告不为0。
糊涂窗口综合症:
接收端通告了小窗口,发送端立即发送小数据,导致网络太多小数据。
解决方法:
接收端不通告小窗口。
发送端不发送小数据。
相关文章:
《TCP/IP详解 卷一》第15章 TCP数据流与窗口管理
目录 15.1 引言 15.2 交互式通信 15.3 延时确认 15.4 Nagle 算法 15.4.1 延时ACK与Nagle算法结合 15.4.2 禁用Nagle算法 15.5 流量控制与窗口管理 15.5.1 滑动窗口 15.5.2 零窗口与TCP持续计时器 15.5.3 糊涂窗口综合征 15.5.4 大容量缓存与自动调优 15.6 紧急机制…...
ContentType类型总结
ContentType类型总结 Content-Type是一个HTTP头部字段,用于指示资源的媒体类型(MIME类型),以及可选的字符集和编码方式。它告诉浏览器或其他客户端如何解释接收到的数据。以下是一些常见的Content-Type类型及其用途: t…...
基于脚手架创建vue工程
环境要求: node.js:前端项目的运行环境 npm:javascript的包管理器 vue cli:项目脚手架 忘了自己有没有安装可以通过在黑窗口输入命令看一下 node -v npm -v 这里出现版本号就说明已经安装了 安装脚手架的命令:npm i vue/cli -g 创建vue基础工程 1.在一个没…...
【Http】OSI 和 TCP/IP,OSI,TCP/IP为什么网络要分层?
目录 OSI 和 TCP/IP OSI TCP/IP 为什么网络要分层? OSI 和 TCP/IP OSI  GPIO(2)输出
1.点亮LED 1.1 推挽接法和开漏接法 要想点亮LED,有两种接法 推挽接法: 向寄存器写1,引脚输出高电平,LED点亮;向寄存器写0,引脚输出低电平,LED熄灭。 开漏接法: 向寄存器写0&…...
shell脚本一键部署docker
Docker介绍 Docker 是一个开源的平台,用于开发、交付和运行应用程序。它利用容器化技术,可以帮助开发人员更轻松地打包应用程序及其依赖项,并将其部署到任何环境中,无论是开发工作站、数据中心还是云中。以下是 Docker 的一些关键…...
vue2实现拖拽排序效果
1、首先下载 vuedraggable 插件 npm i -S vuedraggable2、使用方法 <template><div><div style"display: flex; justify-content: center; align-items: center"><div style"width: 120px; height: 60px; line-height: 60px; text-align…...
数据结构实验:二叉排序树
题目描述 对应给定的一个序列可以唯一确定一棵二叉排序树。然而,一棵给定的二叉排序树却可以由多种不同的序列得到。例如分别按照序列{3,1,4}和{3,4,1}插入初始为空的二叉排序树,都得到一样的结果。你的任务书对于输入的各种序列,判断它们是否…...
Java类加载流程?
Java类加载过程是指将.class文件中的字节码数据加载到内存中,并生成对应的Class对象的过程。Java类加载器(ClassLoader)负责执行这个任务。Java类加载过程主要包括以下几个步骤: 加载(Loading):…...
Docker从0到1的开始【入门篇】
Docker是一种流行的容器化平台,它允许开发人员将应用程序及其所有依赖项打包到一个标准化的单元中,从而实现快速部署和可移植性。在本文中,我们将列出一些常用的Docker命令,以帮助您更好地了解和使用Docker。 1. 安装Docker 要安…...
@ResponseStatus
目录 概述: 用途: 参数: 注意事项: 自定义异常类: 底层原理: 概述: 在 Spring MVC 中,我们有很多方法来设置 HTTP 响应的状态码其中最直接的方法:使用 ResponseSt…...
高效加载大文件(pandas+dask)
一、仅用pd加载大文件(iterator、chunksize) 要使用Pandas进行高效加载超大文件,我们通常会利用其内置的分块(chunk)处理功能。不过,请注意,Pandas本身并不支持多线程读取文件;它更倾向于单线程中进行块处理…...
游戏引擎分层简介
游戏引擎分层架构(自上而下) 工具层(Tool Layer) 在一个现代游戏引擎中,我们最先看到的可能不是复杂的代码,而是各种各样的编辑器,利用这些编辑器,我们可以制作设计关卡、角色、动画…...
向爬虫而生---Redis 探究篇6<Redis的Bigkey问题介绍>
前言: 随着数据规模的增长,Redis的BigKey问题也开始显现。 BigKey问题主要指的是存储了大量数据的key,这可能给Redis的性能和可用性带来负面影响。当一个key的数据量过大时,会占用宝贵的内存资源,拖慢Redis的响应速度。此外,存储和恢复这些BigKey也会变得困难和耗时,增…...
【开源物联网平台】FastBee认证方式和MQTT主题设计
🌈 个人主页:帐篷Li 🔥 系列专栏:FastBee物联网开源项目 💪🏻 专注于简单,易用,可拓展,低成本商业化的AIOT物联网解决方案 目录 一、接入步骤 1.1 设备认证 1.2 设备交…...
Ubuntu Qt控制终端运行ros
文章目录 gnome-terminalQt 通过QProcess类Qt 通过system gnome-terminal 在Ubuntu中可以使用man gnome-terminal命令查看gnome-terminal的使用指南,也可在ubuntu manuals查看: NAMEgnome-terminal — 一个终端仿真应用.概要gnome-terminal [-e, --c…...
mysql 性能调优参数配置文件
########################################################################### ## my.cnf for MySQL 8.0.x # ## 本配置参考 https://imysql.com/my-cnf-wizard.html # ## 注意: …...
windows右键新建文件没有txt文本文档怎么办?
我碰到此问题,按照以下方法改了注册表, 重启之后就正常了(没有注销,只是单纯重启)。以下方法来自AI: 如果在注册表的 .txt 路径下没有找到 ShellNew 键,你可以尝试手动创建这个键和所需的值来恢…...
已读不回,我又玻璃心了
最近有点上火,3个询盘给我整我无语了,难道我还没修炼到家?玻璃心又出来作祟了? 客户A急火火的发我一个文件,需求内容ios客户端调整,让我按照需求给找个人处理下,我收到后抓紧时间摇人࿰…...
面试经典150题(105-107)
leetcode 150道题 计划花两个月时候刷完之未完成后转,今天(第2天)完成了3道(105-107)150 105.(191. 位1的个数)题目描述: 编写一个函数,输入是一个无符号整数(以二进制串的形式&am…...
盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...
10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...
【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案
目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后,迭代器会失效,因为顺序迭代器在内存中是连续存储的,元素删除后,后续元素会前移。 但一些场景中,我们又需要在执行删除操作…...
c++第七天 继承与派生2
这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分:派生类构造函数与析构函数 当创建一个派生类对象时,基类成员是如何初始化的? 1.当派生类对象创建的时候,基类成员的初始化顺序 …...
uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)
UniApp 集成腾讯云 IM 富媒体消息全攻略(地理位置/文件) 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型,核心实现方式: 标准消息类型:直接使用 SDK 内置类型(文件、图片等)自…...
