《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…...
国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...
Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...
零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
华为OD机考-机房布局
import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...
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…...
django blank 与 null的区别
1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是,要注意以下几点: Django的表单验证与null无关:null参数控制的是数据库层面字段是否可以为NULL,而blank参数控制的是Django表单验证时字…...
【无标题】湖北理元理律师事务所:债务优化中的生活保障与法律平衡之道
文/法律实务观察组 在债务重组领域,专业机构的核心价值不仅在于减轻债务数字,更在于帮助债务人在履行义务的同时维持基本生活尊严。湖北理元理律师事务所的服务实践表明,合法债务优化需同步实现三重平衡: 法律刚性(债…...
【深度学习新浪潮】什么是credit assignment problem?
Credit Assignment Problem(信用分配问题) 是机器学习,尤其是强化学习(RL)中的核心挑战之一,指的是如何将最终的奖励或惩罚准确地分配给导致该结果的各个中间动作或决策。在序列决策任务中,智能体执行一系列动作后获得一个最终奖励,但每个动作对最终结果的贡献程度往往…...
