《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 
STM32(5) 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…...

javaWebssh药品进销存信息管理系统myeclipse开发mysql数据库MVC模式java编程计算机网页设计
一、源码特点 java ssh药品进销存信息管理系统是一套完善的web设计系统(系统采用ssh框架进行设计开发),对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为TOM…...

计算机设计大赛 深度学习实现语义分割算法系统 - 机器视觉
文章目录 1 前言2 概念介绍2.1 什么是图像语义分割 3 条件随机场的深度学习模型3\. 1 多尺度特征融合 4 语义分割开发过程4.1 建立4.2 下载CamVid数据集4.3 加载CamVid图像4.4 加载CamVid像素标签图像 5 PyTorch 实现语义分割5.1 数据集准备5.2 训练基准模型5.3 损失函数5.4 归…...

Linux系统编程(六)高级IO
目录 1. 阻塞和非阻塞 IO 2. IO 多路转接(select、poll、epoll) 3. 存储映射 IO(mmap) 4. 文件锁(fcntl、lockf、flock) 5. 管道实例 - 池类算法 1. 阻塞和非阻塞 IO 阻塞 IO:会等待操作的…...

Python与FPGA——全局二值化
文章目录 前言一、Python全局128二、Python全局均值三、Python全局OTSU四、FPGA全局128总结 前言 为什么要进行图像二值化,rgb图像有三个通道,处理图像的计算量较大,二值化的图像极大的减少了处理图像的计算量。即便从彩色图像转成了二值化图…...

《Docker极简教程》--Docker的高级特性--Docker Compose的使用
Docker Compose是一个用于定义和运行多容器Docker应用程序的工具。它允许开发人员通过简单的YAML文件来定义应用程序的服务、网络和卷等资源,并使用单个命令来启动、停止和管理整个应用程序的容器。以下是关于Docker Compose的一些关键信息和优势: 定义…...

tidyverse去除表格中含有NA的行
在tidyverse中,特别是使用dplyr包,去除含有NA的行可以通过filter()函数结合is.na()和any()或all()函数来实现。dplyr是tidyverse的一部分,提供了一系列用于数据操作的函数,使数据处理变得更加简单和直观。 以下是一个简单的例子&…...

开源爬虫技术在金融行业市场分析中的应用与实战解析
一、项目介绍 在当今信息技术飞速发展的时代,数据已成为企业最宝贵的资产之一。特别是在${industry}领域,海量数据的获取和分析对于企业洞察市场趋势、优化产品和服务至关重要。在这样的背景下,爬虫技术应运而生,它能够高效地从互…...

使用SMTP javamail发送邮件
一、SMTP协议 SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。SMTP协议属于TCP/IP协议簇,它帮助每台计算机在发送或中转信件时找到下一个目的地。使用javamail编写发送…...

Hello C++ (c++是什么/c++怎么学/c++推荐书籍)
引言 其实C基础语法基本上已经学完,早就想开始写C的博客了,却因为其他各种事情一直没开始。原计划是想讲Linux系统虚拟机安装的,后来考虑了一下还是算了,等Linux学到一定程度再开始相关博客的写作和发表吧。今天写博客想给C开个头…...

最新的前端开发技术(2024年)
关于作者: 还是大剑师兰特:曾是美国某知名大学计算机专业研究生,现为航空航海领域高级前端工程师;CSDN知名博主,GIS领域优质创作者,深耕openlayers、leaflet、mapbox、cesium,canvas࿰…...