| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 网络协议 -> TCP滑动窗口详解 -> 正文阅读 |
|
[网络协议]TCP滑动窗口详解 |
相较于UDP,TCP有以下区别: 这两个功能都是依靠滑动窗口来实现的,本文就来解密TCP中的滑动窗口。 TCP实现可靠传输依靠的有 序列号、自动重传、滑动窗口、确认应答等机制。 序列号首先我们说下序列号,TCP中将要发送的数据包的每个字节都分配了序列号,用来唯一标识一个字节。序列号随着数据包的发送而增加。 只有为每个字节分配一个序列号,每个数据包都对应着一个序列号区间,才能确定哪个数据包发送出现意外了。 序列号的初始化是由操作系统分配的,是一个32位的数字。 TCP初始化序列号不能设置为一个固定值,因为这样容易被攻击者猜出后续序列号,从而遭到攻击。 RFC1948中提出了一个较好的初始化序列号ISN随机生成算法。
M是一个计时器,这个计时器每隔4us加1。 F是一个随机算法,根据源IP、目的IP、源端口、目的端口生成一个随机数值。 确认应答当接收方收到一个数据包后,会直接返回一个ACK包,或者延迟一段时间返回一个ACK包,一次性确认多个数据包。 ACK包中有一个ack字段,代表着seq小于ack的数据包都已经被接收完毕。 自动重传 ARQARQ的详解分析可以看我的另一篇文章ARQ详解 当TCP发送端发送了一个TCP数据包的时候,会设置一个定时器,如果在定时器期间没有收到接收方对这个数据包的确认应答包,也成为ACK包,就会重新发送对应的TCP数据包。 自动重传有以下两个原因: 超时时间的选择 超时时间过长存在的问题: 超时时间过短存在的问题: 重传超时时间简称为RTO RTO是略大于RTT的。 RTT指的是一个数据包从发送到接收到ACK确认包的花费时间,RTT是会随着网络的变化而变化,是会波动的。 滑动窗口的出现原因滑动窗口 分为 发送窗口 和 接收窗口。 发送窗口 用来 发送数据。 接收窗口 用来 接收数据。 客户端和服务器端 都有一个 发送窗口 和 接收窗口。 为什么会引入滑动窗口呢? 如果不存在发送窗口的话,TCP发送一个数据包后会等待ACK包,因为必须要保存对应的数据包,数据包很有可能需要重新发送。 这样的话发送效率会很慢。大部分时间都在等待。 引入了发送窗口,发送窗口的做法是: 只要处于窗口范围中的字节都可以被发送,不需要等待前面字节的ack包。 发送窗口的本质就是在操作系统中开辟的一块缓冲区,用来存放当前需要发送的数据。当接收到ack的时候,会将seq小于ack的数据从缓冲区中移除,可以发送新的数据。 如果发送窗口的大小为3个TCP数据包,那么发送方就可以连续发送3个TCP数据包,而不用等待前2个数据包的ack包。 滑动窗口详解发送窗口
TCP中用三个指针来区分这个四个部分 这时还允许发送数据,就会将可用窗口中的数据发送给接收窗口。 这个时候,可用窗口大小为0,这个时候会等待接收方发送ack包。 如果这个时候如果接收一个ack包为37,这个时候发送窗口会向右边移动5位,52-56会变成可用窗口。 接收窗口 接收窗口中的字节序列号都是与发送窗口一一对应的。 2、接收窗口中的数据 3、还未收到的数据 接收窗口由一个RCV_NEXT和接收窗口大小window来维护。 接收窗口有以下情况: 1、当数据包的seq == RCV_NEXT的数据包的时候,将接收窗口的RCV_NEXT右移到第一个空的槽位中; 2、当数据包的seq > RCV_NEXT 并且 seq < RCV_NEXT+ window的时候,会将其加入到滑动窗口中对应的位置。 3、如果数据包的seq < RCV_NEXT,说明该数据包已经被接收了,但是对应的ack包因为阻塞或者异常没有发送到发送方。 滑动窗口的大小发送窗口的大小要取决于接收窗口,如果发送窗口大于接收窗口的大小,会导致接收窗口无法完全接收数据包,导致一些数据包被丢弃,导致发送窗口的超时重传,浪费资源。 tcp报文头部中有一个window字段,代表着接收窗口的接收数据能力,发送窗口会根据window字段来调整发送窗口大小,保证接收窗口正常接收数据包。 发送窗口的大小不能超过接收窗口的大小,否则接收窗口不能正常接收数据。 |
|
网络协议 最新文章 |
使用Easyswoole 搭建简单的Websoket服务 |
常见的数据通信方式有哪些? |
Openssl 1024bit RSA算法---公私钥获取和处 |
HTTPS协议的密钥交换流程 |
《小白WEB安全入门》03. 漏洞篇 |
HttpRunner4.x 安装与使用 |
2021-07-04 |
手写RPC学习笔记 |
K8S高可用版本部署 |
mySQL计算IP地址范围 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 | -2024/12/29 11:25:27- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |
数据统计 |