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

滑动窗口技术详解

滑动窗口技术详解

目录

  1. 滑动窗口的核心思想
  2. 不同协议中的具体做法
  3. 优势与局限
  4. TCP 滑动窗口工作流程示意
  5. 通用滑动窗口 C++ 实现
  6. 总结

一、滑动窗口的核心思想

滑动窗口是一种用于流量控制可靠传输的技术,主要解决以下问题:

  1. 提高信道利用率:允许发送方在未收到确认的情况下连续发送多个数据单元,而不是每发一个就停下来等待确认。
  2. 控制流量:接收方可以通过窗口大小告知发送方自己当前能接收的数据量,防止接收方缓冲区溢出。
  3. 实现按序交付与重传:窗口内的分组按顺序编号,接收方根据序号判断是否有丢包,发送方根据确认信息决定重传哪些分组。

基本机制

  • 发送方维护一个发送窗口,表示可以发送但还未被确认的分组范围。
  • 接收方维护一个接收窗口,表示可以接收的分组范围。
  • 窗口会随着数据的发送、确认以及超时事件向前「滑动」,因此称为滑动窗口

二、不同协议中的具体做法

2.1 TCP(Transmission Control Protocol)

TCP 是滑动窗口最经典的应用场景之一。

  • 发送窗口:由**拥塞窗口(cwnd)接收方通告窗口(rwnd)**共同决定,实际可用窗口 = min(cwnd, rwnd)
  • 接收窗口:接收方在 ACK 报文中通告自己剩余的缓冲区大小。
  • 滑动过程:每收到一个 ACK,窗口左边界右移;新数据被确认后,窗口整体向右滑动。
  • 特点:支持可变窗口大小、流量控制、拥塞控制(慢启动、拥塞避免等)。

2.2 HDLC(High-Level Data Link Control)

HDLC 是面向比特的数据链路层协议,使用固定长度的滑动窗口进行流量控制。

  • 窗口大小:由协议参数 W 决定,W=7 表示可连续发送 7 帧而不需确认。
  • 确认方式:可以是捎带确认(piggybacking)或单独的 RR(Receive Ready)帧。
  • 滑动过程:收到对第 N 帧的确认后,窗口向前滑动到第 N+1 帧。

2.3 PPP(Point-to-Point Protocol)

PPP 在数据链路层也使用类似滑动窗口的机制(在 LCP 协商阶段可启用)。

  • 窗口大小:可配置,通常为 1(无流量控制)或更大。
  • 确认与重传:使用超时重传机制,窗口滑动依赖于收到正确的确认帧。

2.4 X.25 分组交换网络

X.25 在数据链路层和分组层都使用滑动窗口。

  • 链路层:类似 HDLC,使用固定窗口大小。
  • 分组层:窗口大小可动态协商,用于控制端到端的数据流。

2.5 实时通信与多媒体协议(如 RTP/RTCP 扩展)

RTP 本身不强制滑动窗口,但在某些实现中,为处理网络抖动和丢包,会采用类似滑动窗口的缓冲区管理策略,对接收到的数据包进行有序重组和播放。


三、优势与局限

优势

  • 提高信道利用率,减少等待时间。
  • 提供流量控制,防止接收方过载。
  • 便于实现可靠传输和重传机制。

局限

  • 需要维护窗口状态,增加协议复杂度。
  • 在高速网络中,窗口大小可能成为性能瓶颈(需配合拥塞控制算法)。
  • 对乱序到达的处理需要额外机制(如选择重传 SACK)。

四、TCP 滑动窗口工作流程示意

4.1 基本概念

在 TCP 中,发送窗口由两部分组成:

  • 已发送但未确认(In-Flight)
  • 可以发送但尚未发送(Available)

窗口大小 = min(拥塞窗口 cwnd, 接收方通告窗口 rwnd)

4.2 初始状态示例

假设窗口大小为 5,序列号范围 0~4,初始时发送方已发送 Seq=0、1,未收到确认:

发送窗口: [0][1][2][3][4] ↑ ↑ 左边界 右边界 已发送未确认 可发送

4.3 流程步骤

Step 1:初始发送
发送方发送 Seq=0、Seq=1,此时已发送未确认:0,1;可发送:2,3,4。

Step 2:收到部分确认
收到 ACK=2(表示 Seq=0,1 已收到),窗口左边界滑动到 2;已发送未确认为空,可发送:2,3,4 及新序号 5,6。

Step 3:继续发送
发送 Seq=2、Seq=3,已发送未确认:2,3;可发送:4,5,6。

Step 4:收到累积确认
收到 ACK=4(Seq=2,3 已收到),左边界滑到 4;可发送:4,5,6,7,8。

Step 5:超时重传
若 Seq=4 超时未确认,发送方重传 Seq=4,窗口不变直到收到 ACK;已发送未确认:4(重传);可发送:5,6,7,8。

Step 6:接收方窗口变化
若接收方缓冲区变小,通告 rwnd=3,则发送窗口上限缩小;左边界=4 时右边界不能超过 6,可发送只有 4,5,6。

4.4 关键点总结

  1. 窗口滑动:每次收到 ACK,左边界右移;右边界随发送新数据或窗口大小调整而移动。
  2. 流量控制:接收方通过 rwnd 限制发送速率。
  3. 拥塞控制:cwnd 根据网络状况动态调整,与 rwnd 共同决定实际窗口。
  4. 重传机制:超时或收到重复 ACK 时触发重传,窗口暂时不滑动。

五、通用滑动窗口 C++ 实现

以下为通用的 C++ 滑动窗口实现模板,不依赖具体协议,仅实现核心的发送窗口管理逻辑:窗口初始化与动态调整、数据发送与确认、窗口滑动、超时重传检测。可基于此适配 TCP、HDLC 等协议。

#include<iostream>#include<unordered_map>#include<queue>#include<string>#include<chrono>#include<thread>// 模拟数据包结构structPacket{intseq_num;std::string data;boolis_acked;std::chrono::steady_clock::time_point send_time;};classSlidingWindow{private:intwindow_size;intbase;intnext_seq_num;std::unordered_map<int,Packet>unacked_packets;std::queue<Packet>packet_buffer;public:SlidingWindow(intsize):window_size(size),base(0),next_seq_num(0){}voidadd_data_to_send(conststd::string&data){packet_buffer.push({next_seq_num,data,false,std::chrono::steady_clock::now()});next_seq_num++;}voidtry_send(){while(unacked_packets.size()<window_size&&!packet_buffer.empty()){Packet pkt=packet_buffer.front();packet_buffer.pop();pkt.send_time=std::chrono::steady_clock::now();unacked_packets[pkt.seq_num]=pkt;std::cout<<"发送数据包: Seq="<<pkt.seq_num<<", Data="<<pkt.data<<std::endl;}}voidreceive_ack(intack_num){if(ack_num>base){for(inti=base;i<ack_num;++i){unacked_packets.erase(i);}base=ack_num;std::cout<<"收到 ACK="<<ack_num<<", 窗口滑动到 base="<<base<<std::endl;}else{std::cout<<"收到重复 ACK="<<ack_num<<std::endl;}}voidcheck_timeout(inttimeout_ms=1000){autonow=std::chrono::steady_clock::now();for(auto&[seq,pkt]:unacked_packets){autoelapsed=std::chrono::duration_cast<std::chrono::milliseconds>(now-pkt.send_time).count();if(elapsed>timeout_ms){std::cout<<"超时重传: Seq="<<seq<<std::endl;pkt.send_time=now;}}}voidprint_status(){std::cout<<"当前窗口: base="<<base<<", next_seq="<<next_seq_num<<", 未确认包数量="<<unacked_packets.size()<<std::endl;}};intmain(){SlidingWindowsw(3);sw.add_data_to_send("Hello");sw.add_data_to_send("World");sw.add_data_to_send("TCP");sw.add_data_to_send("Protocol");sw.try_send();sw.print_status();std::this_thread::sleep_for(std::chrono::milliseconds(500));sw.receive_ack(2);sw.try_send();sw.print_status();std::this_thread::sleep_for(std::chrono::milliseconds(1200));sw.check_timeout(1000);return0;}

代码说明

  • SlidingWindow 类window_size为最大可发送未确认数量;base为窗口左边界;next_seq_num为下一个要分配的序列号;unacked_packets记录已发送未确认的包;packet_buffer模拟待发送数据。
  • 主要方法add_data_to_send添加数据;try_send在窗口未满时发送;receive_ack处理确认并滑动窗口;check_timeout检测超时并重传;print_status打印状态。
  • 可扩展:可加入拥塞控制(动态调整window_size)、SACK 支持,以及替换为真实网络 I/O。

六、总结

滑动窗口的核心思想是通过维护一个可动态调整的发送/接收范围,实现高效、可控的数据传输。它在TCP、HDLC、PPP、X.25等协议中都有不同的实现方式,但目标一致:在保证可靠性的前提下最大化信道利用率

http://www.jsqmd.com/news/349085/

相关文章:

  • 2026年公路球型双向活动支座性价比排名,哪家好? - 工业品网
  • 2026 年 2 月南京就业率最高专科院校 TOP10 口碑榜,航空特色、双师师资与实训平台深度对比(附选型指南) - 资讯焦点
  • linux内核启动流程
  • 用RS6013A实现“呼吸+心跳”实验(含FFT分析)
  • 2026年避雷针专业推荐:主动式/提前放电/优化避雷针及避雷带接地系统供应商精选 - 品牌推荐官
  • 云计算基础详解:容器与云原生的核心逻辑及实践价值
  • YOLO + Flask + Vue 前后端分离 Web 检测系统 yolo Flask web端图片视频检测系统 使用Flask作为后端和vue作为前端,前后端分离 可以替换自己的模型
  • Web1 到 Web3 技术演进详解
  • 智慧仓储新纪元:2026年堆垛机立体库核心生产企业深度解析 - 资讯焦点
  • 效率直接起飞!备受喜爱的降AI率软件 —— 千笔AI
  • 红外性诱测报仪红外性诱测报灯红外靶向害虫自动测报系统
  • mask-rcnn_hrnetv2p-w32-1x_coco:腰果质量分级与缺陷检测的深度学习实践指南
  • 2026雅思口语APP天花板!亲测这3款让你短期冲7,告别无效练习 - 资讯焦点
  • 别再瞎找了!千笔AI,本科生降重首选!
  • 全国工具钢优质厂家有哪些?优先选哪些维度筛选? - 非研科技
  • 『React』组件副作用,useEffect讲解
  • 探索 6 机 30 节点电力系统的混合规划求解
  • 综述不会写?千笔·专业学术智能体,本科生论文救星!
  • 5秒开服,你的应用部署还卡在“加载中”吗?
  • 2分钟,生成你的数字分身:华为云数字人解锁企业高效未来
  • AI协议模糊测试:2026年热度趋势与专业应用
  • 多维度商品统计,经营数据实时汇总
  • java+vue基于springboot的果蔬批发系统的设计与实现_2kx2z717
  • 30. 异步和多线程
  • 唐山有哪些信誉好的GEO优化公司推荐 - 工业设备
  • 2026年质量好的四川柴油发电机供应商最新推荐权威榜 - 朴素的承诺
  • 2026年正规的CIFF上海潮向生活美学展,CIFF上海都市户外展,CIFF海软体家居技术展公司采购优选榜单 - 品牌鉴赏师
  • java+vue基于springboot的汽车路试数据管理系统设计与实现_9859us78
  • GD32F103C8T6每个引脚介绍和整理
  • 【EI Compendex、Scopus检索】第二届智慧城市与可持续发展国际学术会议(SCSD 2026)