【斯坦福CS144】Lab1

一、实验目的

1.实现一个流重组器——一个将字节流的小块 (称为子串或段 )按正确顺序组装成连续的字节流的模块;

2.深入理解 TCP 协议的工作方式。

二、实验内容

编写一个名为"StreamReassembler"的数据结构,它负责重新组装数据。该结构将接收子串(由一串字节和大数据流中该串的第一个字节的索引组成),并提供一个名为"ByteStream"的输出,其中所有的数据都被正确排序。

三、实验过程

在minnow目录下,输入 git fetch 更新本地源仓库,此处显示更新失败是因为本次实验开始时源仓库已经最新,无需再次更新

输入git merge origin/check1-startercode获取Lab1

获取后输入cmake --build build来判断代码目前是否正常,结果为正常

用文本编辑器查看./src/reassembler.hh

修改代码,代码分析见注释

用文本编辑器查看./src/reassembler.cc

修改代码,代码分析见注释

保存并编译

输入make check1测试程序

全部通过

四、实验体会

1.下图完整地显示了CS144 这门实验的结构

ByteStream 是我们已经在 Lab0 中实现完成的。

我们在Lab1 中实现一个流重组器,一个将字节流的字串或者小段按照正确顺序来拼接回连续字节流的模块。

2.流重组器在 TCP 起到了相当重要的作用。迫于网络环境的限制,TCP 发送者会将数据切割成一个个小段的数据分批发送。但这就可能带来一些新的问题:数据在网络中传输时可能丢失、重排、多次重传等等。而TCP接收者就必须通过流重组器,将接收到的这些重排重传等等的数据包重新组装成新的连续字节流。

3.在调试的时候,所有的评测程序位于build/tests/中,进入此位置进行调试。

五、代码附录

reassembler.hh

#pragma once#include "byte_stream.hh"#include <string>
#include <list>
#include <tuple>class Reassembler
{bool had_last_ {};	// 是否已经插入了最后一个字符串uint64_t next_index_ {};	// 下一个要写入的字节的索引uint64_t buffer_size_ {};	// buffer_中的字节数std::list<std::tuple<uint64_t, uint64_t, std::string>> buffer_ {};/*** \breif 将data推入output流.*/void push_to_output(std::string data, Writer& output);/*** \brief 将data推入buffer暂存区.* \param first_index data的第一个字节的索引* \param last_index  data的最后一个字节的索引* \param data        待推入的字符串, 下标为[first_index, last_index]闭区间*/void buffer_push( uint64_t first_index, uint64_t last_index, std::string data );/*** 尝试将buffer中的串推入output流.*/void buffer_pop(Writer& output);public:/** Insert a new substring to be reassembled into a ByteStream.*   `first_index`: the index of the first byte of the substring*   `data`: the substring itself*   `is_last_substring`: this substring represents the end of the stream*   `output`: a mutable reference to the Writer** The Reassembler's job is to reassemble the indexed substrings (possibly out-of-order* and possibly overlapping) back into the original ByteStream. As soon as the Reassembler* learns the next byte in the stream, it should write it to the output.** If the Reassembler learns about bytes that fit within the stream's available capacity* but can't yet be written (because earlier bytes remain unknown), it should store them* internally until the gaps are filled in.** The Reassembler should discard any bytes that lie beyond the stream's available capacity* (i.e., bytes that couldn't be written even if earlier gaps get filled in).** The Reassembler should close the stream after writing the last byte.*/void insert( uint64_t first_index, std::string data, bool is_last_substring, Writer& output );// How many bytes are stored in the Reassembler itself?uint64_t bytes_pending() const;
};

reassembler.cc

#include "reassembler.hh"#include <ranges>
#include <algorithm>using namespace std;
void Reassembler::push_to_output( std::string data, Writer& output ) {next_index_ += data.size();output.push( move( data ) );
}void Reassembler::buffer_push( uint64_t first_index, uint64_t last_index, std::string data )
{// 合并区间auto l = first_index, r = last_index;auto beg = buffer_.begin(), end = buffer_.end();auto lef = lower_bound( beg, end, l, []( auto& a, auto& b ) { return get<1>( a ) < b; } );auto rig = upper_bound( lef, end, r, []( auto& b, auto& a ) { return get<0>( a ) > b; } );if (lef != end) l = min( l, get<0>( *lef ) );if (rig != beg) r = max( r, get<1>( *prev( rig ) ) );// 当data已在buffer_中时,直接返回if ( lef != end && get<0>( *lef ) == l && get<1>( *lef ) == r ) {return;}buffer_size_ += 1 + r - l;if ( data.size() == r - l + 1 && lef == rig ) { // 当buffer_中没有data重叠的部分buffer_.emplace( rig, l, r, move( data ) );return;}string s( 1 + r - l, 0 );for ( auto&& it : views::iota( lef, rig ) ) {auto& [a, b, c] = *it;buffer_size_ -= c.size();ranges::copy(c, s.begin() + a - l);}ranges::copy(data, s.begin() + first_index - l);buffer_.emplace( buffer_.erase( lef, rig ), l, r, move( s ) );
}void Reassembler::buffer_pop( Writer& output ) {while ( !buffer_.empty() && get<0>( buffer_.front() ) == next_index_ ) {auto& [a, b, c] = buffer_.front();buffer_size_ -= c.size();push_to_output( move( c ), output ); buffer_.pop_front();}if ( had_last_ && buffer_.empty() ) {output.close();}
}void Reassembler::insert( uint64_t first_index, string data, bool is_last_substring, Writer& output )
{if ( data.empty() ) {if ( is_last_substring ) {output.close();}return;}auto end_index = first_index + data.size();                  // data: [first_index, end_index)auto last_index = next_index_ + output.available_capacity(); // 可用范围: [next_index_, last_index)if ( end_index < next_index_ || first_index >= last_index ) {return; // 不在可用范围内, 直接返回}// 调整data的范围if ( last_index < end_index ) {end_index = last_index;data.resize( end_index - first_index );is_last_substring = false;}if ( first_index < next_index_ ) {data = data.substr( next_index_ - first_index );first_index = next_index_;}// 若data可以直接写入output, 则直接写入if ( first_index == next_index_ && ( buffer_.empty() || end_index < get<1>( buffer_.front() ) + 2 ) ) {if ( buffer_.size() ) { // 若重叠, 则调整data的范围data.resize( min( end_index, get<0>( buffer_.front() ) ) - first_index );}push_to_output( move( data ), output );} else { // 否则, 将data插入buffer_buffer_push( first_index, end_index - 1, data );}had_last_ |= is_last_substring;// 尝试将buffer_中的数据写入outputbuffer_pop(output);
}uint64_t Reassembler::bytes_pending() const
{return buffer_size_;
}

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

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

相关文章

k8s 中存储之 NFS 卷

目录 1 NFS 卷的介绍 2 NFS 卷的实践操作 2.1 部署一台 NFS 共享主机 2.2 在所有k8s节点中安装nfs-utils 2.3 部署nfs卷 2.3.1 生成 pod 清单文件 2.3.2 修改 pod 清单文件增加 实现 NFS卷 挂载的 参数 2.3.3 声明签单文件并查看是否创建成功 2.3.4 在 NFS 服务器 创建默认发布…

15分钟学 Python 第38天 :Python 爬虫入门(四)

Day38 : Python爬虫异常处理与反爬虫机制 章节1&#xff1a;异常处理的重要性 在爬虫开发过程中&#xff0c;网络请求和数据解析常常会遭遇各种异常。正确的异常处理可以提高程序的稳定性&#xff0c;避免崩溃&#xff0c;并帮助开发者快速定位问题。 章节2&#xff1a;常见…

杠铃检测系统源码分享

杠铃检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vision 研究…

Python | 由高程计算坡度和坡向

写在前面 之前参加一个比赛&#xff0c;提供了中国的高程数据&#xff0c;可以基于该数据进一步计算坡度和坡向进行相关分析。 对于坡度和坡向&#xff0c;这里分享一个找到的库&#xff0c;可以方便快捷的计算。这个库为&#xff1a;RichDEM&#xff0c;官网地址如下 https…

Windows系统编程(四)远程线程

本章内容讲解远程线程 远程线程 我们之前所学过的CreateThread()是创建一个本地线程&#xff0c;其本质是启动一个进程然后执行一个函数。而我们学习网络安全经常会与shellcode打交道&#xff0c;其本质上是以特殊的编程手法所编写的一段普通的代码。这段代码可以在任意环境下…

pWnOS2.0 靶机渗透( cms 渗透,php+mysql 网站渗透,密码碰撞)

pWnOS2.0 靶机渗透( ) 靶机介绍 vulnhub 靶机 本地搭建 由于靶机特性&#xff0c;靶机网卡位nat模式扫不到&#xff0c;原来需要改 nat 的地址 参考方法 https://blog.csdn.net/Bossfrank/article/details/131415257 作者主页 https://blog.csdn.net/Bossfrank?typeblog P…

Hallo部署指南

一、介绍 Hallo是由复旦大学、百度公司、苏黎世联邦理工学院和南京大学的研究人员共同提出的一个AI对口型肖像图像动画技术&#xff0c;可基于语音音频输入来驱动生成逼真且动态的肖像图像视频。 该框架采用了基于扩散的生成模型和分层音频驱动视觉合成模块&#xff0c;提高了…

【Unity学习笔记】解决疑似升级Win11或使用Unity6导致Unity旧版本无法打开的问题

【Unity学习笔记】解决疑似升级Win11或使用Unity6导致Unity旧版本无法打开的问题 一句话省流&#xff1a; 确保项目地址没有任何中文&#xff0c;重新申请个许可证&#xff0c;然后该咋就咋&#xff0c;完事。 ——————————————————————————————…

Oracle登录报错-ORA-01017: invalid username/password;logon denied

接上文&#xff1a;Oracle创建用户报错-ORA-65096: invalid common user or role name 我以为 按照上文在PDB里创建了用户&#xff0c;我以为就可以用PLSQL远程连接了&#xff0c;远程服务器上也安装了对应版本的Oracle客户端&#xff0c;但是我想多了&#xff0c;客户只是新建…

Nginx06-静态资源部署

零、文章目录 Nginx06-静态资源部署 1、静态资源概述 静态资源&#xff1a;是在Web开发中不经常改变的文件&#xff0c;比如图片、CSS样式表、JavaScript脚本文件等。这些资源通常是预先编译好的&#xff0c;不需要服务器端的动态处理。动态资源&#xff1a;是在Web开发中需…

【自动驾驶】《Planning-oriented Autonomous Driving》UniAD论文阅读笔记

1.参考 论文&#xff1a;https://arxiv.org/pdf/2212.10156 代码&#xff1a;https://github.com/OpenDriveLab/UniAD 2.摘要 原来的自动驾驶任务都是分为模块化的&#xff0c;感知&#xff0c;预测&#xff0c;规划等。每个独立的任务可能都优化得很好&#xff0c;但可能会…

深度学习基础—Anchor Boxes与YOLO 算法

前言&#xff1a;在之前的博客中&#xff0c;我依次总结了目标检测算法、算法的卷积改进、Bounding Box预测算法、交并比与非极大值抑制等内容&#xff0c;这些是YOLO 算法的重要细节&#xff0c;现在还差一柄利剑&#xff0c;我们就可以构建YOLO算法了&#xff0c;现在让我们先…

OJ在线评测系统 微服务高级 网关跨域权限校验 集中解决跨域问题 拓展 JWT校验和实现接口限流降级

微服务网关跨域权限校验 集中的去解决一下跨域 这段代码是用来配置跨源资源共享&#xff08;CORS&#xff09;过滤器的。它创建了一个 CorsConfiguration 实例&#xff0c;允许所有方法和头部&#xff0c;并支持凭证&#xff08;如 Cookies&#xff09;。setAllowedOriginPat…

【论文笔记】DKTNet: Dual-Key Transformer Network for small object detection

【引用格式】&#xff1a;Xu S, Gu J, Hua Y, et al. Dktnet: dual-key transformer network for small object detection[J]. Neurocomputing, 2023, 525: 29-41. 【网址】&#xff1a;https://cczuyiliu.github.io/pdf/DKTNet%20Dual-Key%20Transformer%20Network%20for%20s…

本田汽车投资SiLC Technologies:携手共促自动驾驶技术新飞跃

SiLC Technologies获本田汽车投资:加速自动驾驶技术革新 近日,硅谷光子学初创公司SiLC Technologies宣布获得本田汽车的投资,这一合作标志着双方将共同推进自动驾驶技术领域的革新与发展。本田此次投资不仅体现了对SiLC Technologies技术实力的认可,也彰显了本田在自动驾驶…

MATLAB工具库:数据统计分析工具MvCAT、MhAST等

MATLAB工具库&#xff1a;数据统计分析工具MvCAT、MhAST等 工具1&#xff1a;Multivariate Copula Analysis Toolbox (MvCAT)MATLAB中运行 工具2&#xff1a;Multi-hazard Scenario Analysis Toolbox (MhAST) 参考 The University of California-软件库-Software 工具1&#xf…

【源码+文档】基于SpringBoot+Vue校园智慧迎新服务平台

&#x1f6a9;如何选题&#xff1f; 如何选题、让题目的难度在可控范围&#xff0c;以及如何在选题过程以及整个毕设过程中如何与老师沟通&#xff0c;这些问题是需要大家在选题前需要考虑的&#xff0c;具体的方法我会在文末详细为你解答。 &#x1f6ad;如何快速熟悉一个项目…

饮料瓶识别系统源码分享

饮料瓶识别系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vision 研…

QSerialPort 串口通信示例

之前使用过MFC写过串口通信的示例&#xff0c;今年学了Qt&#xff0c;特意使用Qt写了串口通信的示例&#xff0c;发现比MFC要容易一些&#xff0c; MFC串口示例如下&#xff1a; Qt示例如下&#xff1a; Qt这个做的很简单&#xff0c;主要还是想验证一下api&#xff0c; 核心…

设计模式的学习

OO:Object-Oriented 面向对象 --- 《Head First设计模式》 这本书是用java写的&#xff0c;我是写C的&#xff0c;用C来写相关的代码 --- p2&#xff08;第二页&#xff09; #ifndef DUCK_H #define DUCK_H/*** brief The Duck class 鸭子类*/ class Duck { public:D…