cs144 LAB1 基于滑动窗口的碎片字节流重组器

一.StreamReassembler.capacity 的意义

StreamReassembler._capacity 的含义:

capacity

  • ByteStream 的空间上限是 capacity
  • StreamReassembler 用于暂存未重组字符串片段的缓冲区空间 StreamReassembler.buffer 上限也是 capacity
  • 蓝色部分代表了已经被上层应用读取的已重组数据
  • 绿色部分代表了 ByteStream 中已经重组并写入但还未被读取的字节流所占据的空间大小
  • 红色部分代表了 StreamReassembler 中已经缓存但未经重组的若干字符串片段所占据的空间大小
  • 同时绿色和红色两部分加起来的空间总占用大小不会超过 capacity(事实上会一直小于它)

从代码层面来看:

  • first unread 的索引等于 ByteStream 的 bytes_read() 函数的返回值(我们一般不关注这个值)
  • first unassembled 的索引等于 ByteStream 的 bytes_write() 函数的返回值(起始就是下一个期望的字节在流中的序号)
  • first unacceptable 的索引等于 ByteStream 的 bytes_read() 加上 capacity 的和(已超过 ByteStream 的 buffer 限制)
  • first unread 和 first unacceptable 这两个边界是动态变化的,每次重组结束都需要更新。

最后,有个很重要点,ByteStream 和 StreamReassembler 的总容量有固定的限制,多余的数据需要丢弃(此需要对端重传数据,这就引出了重传等知识点)

二.滑动窗口碎片重组算法 

        每次收到的data数据由于网络传输不可靠的原因会产生乱序,重叠。需要对每次收到的碎片序列进行重组。可以定义装配器的窗口大小为capacity,范围为[_first_unassembled,_first_unassembled + _capacity]。超出此范围的字节将被丢弃(实验要求,之后会引出重传)。窗口会随着第一个期望的字节序号进行移动即_first_unassembled。每次计算缓冲区第一个期望字节序号,并保障每个字节碎片都在窗口范围内,这需要对碎片进行裁剪,裁剪过后的碎片可以直接加入缓存区。

        可分为下面几个步骤完成:

1.计算重组器窗口起始位置,结束位置。

2.判断碎片是否合法,不合法则直接丢弃。

3.裁剪碎片,使其满足缓冲区要求。

4.碎片加入缓存区。

5.缓存区写入流。(如果缓冲区头部有元素的话)

6.判断EOF。

        需要注意EOF这里有几个大坑,首先是EOF可能会提早到来,这时不能直接结束流写入需要进行判断。第二是EOF可能与其他流重叠,故而可以记录EOF的合法结束字节位置来判断是否真正需要停止流写入。

#ifndef SPONGE_LIBSPONGE_STREAM_REASSEMBLER_HH
#define SPONGE_LIBSPONGE_STREAM_REASSEMBLER_HH#include "byte_stream.hh"#include <cstdint>
#include <string>
#include <deque>//! \brief A class that assembles a series of excerpts from a byte stream (possibly out of order,
//! possibly overlapping) into an in-order byte stream.
class StreamReassembler {private:// Your code here -- add private members as necessary.std::deque<std::string::value_type> _reassembler_buffer;  //重组器缓冲区std::deque<bool> _bytes_flag; //重组器字节标志位std::size_t _unassembaled_bytes = 0;  //未被装配的字节bool _is_eof = false; //判断子序列是否含有EOFstd::size_t _eof_index = 0; //记录EOF段最后一个字节的位置ByteStream _output;  //!< The reassembled in-order byte streamsize_t _capacity;    //!< The maximum number of bytespublic://! \brief Construct a `StreamReassembler` that will store up to `capacity` bytes.//! \note This capacity limits both the bytes that have been reassembled,//! and those that have not yet been reassembled.StreamReassembler(const size_t capacity);//! \brief Receive a substring and write any newly contiguous bytes into the stream.//!//! The StreamReassembler will stay within the memory limits of the `capacity`.//! Bytes that would exceed the capacity are silently discarded.//!//! \param data the substring//! \param index indicates the index (place in sequence) of the first byte in `data`//! \param eof the last byte of `data` will be the last byte in the entire streamvoid push_substring(const std::string &data, const uint64_t index, const bool eof);//! \name Access the reassembled byte stream//!@{const ByteStream &stream_out() const { return _output; }ByteStream &stream_out() { return _output; }//!@}//! The number of bytes in the substrings stored but not yet reassembled//!//! \note If the byte at a particular index has been pushed more than once, it//! should only be counted once for the purpose of this function.size_t unassembled_bytes() const;//! \brief Is the internal state empty (other than the output stream)?//! \returns `true` if no substrings are waiting to be assembledbool empty() const;
};#endif  // SPONGE_LIBSPONGE_STREAM_REASSEMBLER_HH
#include "stream_reassembler.hh"// Dummy implementation of a stream reassembler.// For Lab 1, please replace with a real implementation that passes the
// automated checks run by `make check_lab1`.// You will need to add private members to the class declaration in `stream_reassembler.hh`template <typename... Targs>
void DUMMY_CODE(Targs &&... /* unused */) {}using namespace std;StreamReassembler::StreamReassembler(const size_t capacity) : 
_reassembler_buffer(capacity, '\0'),
_bytes_flag(capacity, false),
_output(capacity),
_capacity(capacity) {}//! \details This function accepts a substring (aka a segment) of bytes,
//! possibly out-of-order, from the logical stream, and assembles any newly
//! contiguous substrings and writes them into the output stream in order.
void StreamReassembler::push_substring(const string &data, const size_t index, const bool eof) {//判断index是否合法std::size_t _first_unassembled = _output.bytes_written();   //每次计算期望的字节序号std::size_t _first_unacceptable = _first_unassembled + _capacity;   //第一个不允许装配的字节序号if(index >= _first_unacceptable || index + data.length() < _first_unassembled)return;//滑动窗口位于[_first_unassembled,_first_unassembled + _capacity]之间只有其中元素可以入队,对data进行裁剪std::size_t new_index = index;std::size_t new_end = index + data.length();if(new_index < _first_unassembled)new_index = _first_unassembled;if(new_end >= _first_unacceptable)new_end = _first_unacceptable;//裁剪完成后data的起始位置符合滑动窗口要求,入队for(std::size_t i = new_index; i < new_end; ++i){if(!_bytes_flag[i - _first_unassembled]){_reassembler_buffer[i - _first_unassembled] = data[i - index];   //入队_bytes_flag[i - _first_unassembled] = true;  //相应标志位置位++_unassembaled_bytes;  //缓冲区计数增加}}//写入流操作(当装配缓冲区头部有元素那么一定是顺序的直接写入流)string wait_to_write{};while(_bytes_flag.front()){wait_to_write += _reassembler_buffer.front();_bytes_flag.pop_front();_reassembler_buffer.pop_front();_bytes_flag.emplace_back(false);        //维护缓冲区大小_reassembler_buffer.emplace_back('\0'); //维护缓冲区大小}if(wait_to_write.size() > 0){int out_bytes = _output.write(std::move(wait_to_write));_unassembaled_bytes -= out_bytes;}//检查eofif(eof){_is_eof = true;_eof_index = new_end;}if(_is_eof && _eof_index == _output.bytes_written())_output.end_input();
}size_t StreamReassembler::unassembled_bytes() const { return _unassembaled_bytes; }bool StreamReassembler::empty() const { return _unassembaled_bytes == 0; }

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/30182.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

神火股份电子商务平台(数字化招采平台),构建企业数字活力

为推进数字化转型升级进程&#xff0c;神火股份携手信源信息建设电子商务平台&#xff0c;近日&#xff0c;该平台已实现验收&#xff0c;为企业高质量发展注入“数字活力”。 河南神火煤电股份有限公司&#xff08;简称“神火股份”&#xff09;是以煤炭、发电、电解铝生产及…

2024年CCSK认证培训招生简章公开

CCSK认证培训背景 本课程旨在确保与云计算相关的从业人员对云安全威胁和云安全最佳 实践有一个全面的了解和广泛的认知。包含了广泛的云安全知识&#xff0c;涵 盖了体系结构、合规治理、加密和虚拟化等主题。自2010年推出以 来&#xff0c;成千上万的IT和安全专业人员通过CCSK…

snmp-check一键获取SNMP信息(KALI工具系列二十一)

目录 1、KALI LINUX 简介 2、snmp-check工具简介 3、在KALI中使用onesixtyone 3.1 目标主机IP&#xff08;win&#xff09; 3.2 KALI的IP 4、操作示例 4.1 SNMP 检查 4.2 指定 SNMP 端口 4.3 指定社区字符串 4.4 详细输出 4.5 指定多项 5、总结 1、KALI LINUX 简介…

Danikor智能拧紧轴控制器过压维修知识

【丹尼克尔拧紧轴控制器故障代码维修】 【丹尼克尔Danikor控制器维修具体细节】 丹尼克尔拧紧轴控制器作为一种高精度的电动拧紧工具&#xff0c;广泛应用于各种工业生产线。然而&#xff0c;在使用过程中&#xff0c;由于各种原因&#xff0c;可能会出现Danikor扭矩扳手控制…

【案例分析】一文讲清楚SaaS产品运营的六大杠杆是什么?具体怎么运用?

在SaaS&#xff08;软件即服务&#xff09;行业&#xff0c;如何快速获取用户并实现持续增长一直是企业关注的重点。近年来&#xff0c;分销裂变策略因其高效性和低成本特性&#xff0c;成为许多SaaS企业实现快速增长的秘诀。下面&#xff0c;我们将通过一个具体的案例来剖析成…

Ubuntu-24.04-live-server-amd64安装界面中文版

系列文章目录 Ubuntu安装qemu-guest-agent Ubuntu-24.04-live-server-amd64启用ssh Ubuntu乌班图安装VIM文本编辑器工具 文章目录 系列文章目录前言一、准备工作二、开始安装三、测试效果总结 前言 Centos结束&#xff0c;转战Ubuntu。我之所以写这篇文章&#xff0c;是因为我…

精细化,智能费控4.0的竞争内核

出差&#xff0c;在百度百科被释义为&#xff0c;受派遣到外地或负担临时任务。 这是一个对员工清晰对管理却笼统的定义。站在企业费用管理的角度&#xff0c;出差可细分为会议出差、培训出差、市场拓展出差、项目出差、驻外回厂出差、探亲出差、售后维修出差、新人报道出差等不…

防爆气象站:化工厂区气象环境监测的最佳选择

在化工厂区&#xff0c;气象环境监测至关重要&#xff0c;它直接关系到生产安全、环境保护以及员工健康。防爆气象站作为专业的监测设备&#xff0c;凭借其独特的防爆性能和精准的数据监测能力&#xff0c;成为化工厂区气象环境监测的最佳选择。 防爆气象站采用先进的防爆技术…

访问网络 测试没有问题,正式有问题

ping -c 5 -i 1 www.baidu.com 首先检查一下网络&#xff0c;在正式服务器ping 一下要访问的地址。 如果不行&#xff0c;联系网络管理员开通。 笔者因为这个问题浪费了半天时间&#xff0c;一开始都以为是代码问题 以后大家看到这个异常&#xff0c;解决如下&#xff1a; …

逻辑卷管理器 (LVM) 简介

古老的 e5 主机目前有这些存储设备 (硬盘): 系统盘 (M.2 NVMe SSD 480GB), 数据盘 (3.5 英寸 SATA 硬盘 4TB x2). 窝决定使用 LVM 对数据盘进行管理. 逻辑卷管理器 (LVM) 可以认为是一种 (单机) 存储虚拟化 技术. 多个物理存储设备 (PV) 组成一个存储池 (VG), 然后划分虚拟分区…

docker ce的使用介绍

docker docker17.03以后 docker ce&#xff0c;社区免费版&#xff0c;vscode的docker插件使用的该版本&#xff08;默认windows只支持windows容器&#xff0c;linux支持linux容器&#xff09;docker ee&#xff0c;企业版本 docker17.03以前 docker toolbox&#xff0c;基于…

手把手带你从异构数据库迁移到崖山数据库

一、数据迁移简介 1.典型场景与需求 在国产化浪潮下&#xff0c;数据库系统的国产化替代成为了一个日益重要的议题&#xff0c;有助于企业降低对外依赖&#xff0c;提升信息安全和自主性。 以Oracle、MySQL为代表的传统关系型数据库管理系统&#xff0c;在企业应用中占据了重要…

7zip安装后压缩包图标显示空白解决办法

记录安装7zip软件后&#xff0c;出现了如下的图标是空白的问题: &#xff08;虽然我最终解决了但是我不确定是哪一步起的作用&#xff0c;但是我也懒得再情景复现了。&#xff09; 我的解决过程是&#xff1a; 在开始菜单栏搜索“7zip ”然后点击“打开。 然后点击 &#xf…

【送模板】5张图,帮你轻松搞懂OKR工作法

OKR是目标与关键结果法的缩写&#xff0c;OKR运用在工作中就是强调对业务进行逻辑思考&#xff0c;找到目标与关键结果之间的因果关系。这种因果关系的是否准确决定我们努力的价值。 OKR是一种高效的目标管理方法。“O”就是object&#xff0c;目标的意思&#xff0c;“kr”就…

81600B keysight 是德 可调谐激光源 简述

KEYSIGHT 81600B 是可调谐激光源模块&#xff0c;广泛应用于光通信和光学测试领域。该系列产品通过低自发源发射&#xff08;low SSE&#xff09;技术实现了高信噪比&#xff08;>70 dB/nm&#xff09;&#xff0c;并具有快速准确的扫描能力&#xff0c;覆盖1260 nm至1640 n…

2024 年 Python 基于 Kimi 智能助手 Moonshot Ai 模型搭建微信机器人(更新中)

注册 Kimi 开放平台 Kimi&#xff1a;https://www.moonshot.cn/ Kimi智能助手是北京月之暗面科技有限公司&#xff08;Moonshot AI&#xff09;于2023年10月9日推出的一款人工智能助手&#xff0c;主要为用户提供高效、便捷的信息服务。它具备多项强大功能&#xff0c;包括多…

flutter 导出iOS问题3

更新flutter版本后 macminihaomacMiniaodeMini SocialIM % flutter --version Flutter 3.7.12 • channel stable • https://github.com/flutter/flutter.git Framework • revision 4d9e56e694 (1 year, 2 months ago) • 2023-04-17 21:47:46 -0400 Engine • revision 1a6…

MDPO:Conditional Preference Optimization for Multimodal Large Language Models

MDPO: Conditional Preference Optimization for Multimodal Large Language Models 相关链接&#xff1a;arxiv 关键字&#xff1a;多模态、大型语言模型、偏好优化、条件偏好优化、幻觉减少 摘要 直接偏好优化&#xff08;DPO&#xff09;已被证明是大型语言模型&#xff08…

什么是“基准测试集”呢?

基准测试集有三部分构成&#xff1a;DocumentSet、QuerySet、RelevantJudgement。在比较多个IR系统孰优孰劣的时候&#xff0c;要做的就是&#xff1a;使用统一的DecumentSet建立索引&#xff0c;然后使用统一的QuerySet去进行查询&#xff0c;最后使用统一的judgement进行评判…

OpenAI新模型发布,免费开放GPT-4o!但只开放一点点...

GPT-4o 中的“o”代表“omni”——指的是 GPT-4o 的多模态。 该模型将向免费客户开放&#xff0c;这意味着任何人都可以通过 ChatGPT 访问 OpenAI 最先进的技术。 GPT-4o 是 OpenAI 昨天晚上发布的新旗舰模型&#xff0c;可以实时推理音频、视觉和文本。 据官方介绍&#xff0…