CS144 lab1 笔记

CS144 lab1 笔记

image-20220122225625163

上图是TCP实现中模块和数据流的安排,我们要实现的就是StreamReassembler

一个字符重组器,将乱序的字符串,按照索引排序,使其成为连续字符,供TCPSenderTCPReceiver使用

  • 有容量限制,超出的字符直接丢掉(不是整个片段)

  • TCP接收到的片段从零开始,不会溢出

  • 任何报文段,只要排好序(重组,去除重叠),就必须放入ByteStream

  • 收到eof表示这个字符流结束了,并且这个字符串为最后一个,但不是现在停止接收,必须等到eof及之前的字符片段全部排序完成并且实现之后才能终止字符流的写入(因为乱序写入)

  • _output对应的是width区域,已读范围不属于_output,这里的变化已经在上一个实验处理好

image-20220122235717632 image-20220122235804651

思路:

  • 用 set 来暂存报文段,按照报文段的 index 大小对比重载 < 运算符。
  • 收到新片段时根据Indexlength并且根据下图重叠情况进行合并,切除

image-20220123001615050

  • 合并后,遍历片段,如果有能与个前面已排序片段合并的就合并,经合并的片段放入ByteStream
  • 如果eof为真,并且全部排序时,停止ByteStream输入
  • 重复上述过程

代码

stream_reassembler.hh

class StreamReassembler {private:// Your code here -- add private members as necessary.ByteStream _output;  //!< The reassembled in-order byte streamsize_t _capacity;    //!< The maximum number of bytessize_t _first_unread = 0;size_t _first_unassembled = 0;size_t _first_unacceptable;bool _eof = false;struct seg {size_t index;size_t length;std::string data;bool operator<(const seg& t) const { return index < t.index; }};std::set<seg> _stored_segs = {};void _add_new_seg(seg &new_seg, bool eof);void _handle_overlap(seg &new_seg);void _stitch_output();void _stitch_one_seg(const seg &new_seg);void _merge_seg(seg &new_seg, const seg &other);public:

*stream_reassembler.cc

#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): _output(capacity), _capacity(capacity), _first_unacceptable(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) {_first_unread = _output.bytes_read();_first_unacceptable = _first_unread + _capacity;seg new_seg = {index, data.length(), data};_add_new_seg(new_seg, eof);_stitch_output();if (empty() && _eof)_output.end_input();
}void StreamReassembler::_add_new_seg(seg &new_seg, const bool eof) {// check capacity limit, if unmeet limit, return// cut the bytes in NEW_SEG that will overflow the _CAPACITY// note that the EOF should also be cut// cut the bytes in NEW_SEG that are already in _OUTPUT// _HANDLE_OVERLAP()// update _EOFif (new_seg.index >= _first_unacceptable)return;bool eof_of_this_seg = eof;if (int overflow_bytes = new_seg.index + new_seg.length - _first_unacceptable; overflow_bytes > 0) {int new_length = new_seg.length - overflow_bytes;if (new_length <= 0)return;eof_of_this_seg = false;new_seg.length = new_length;new_seg.data = new_seg.data.substr(0, new_seg.length);}if (new_seg.index < _first_unassembled) {int new_length = new_seg.length - (_first_unassembled - new_seg.index);if (new_length <= 0)return;new_seg.length = new_length;new_seg.data = new_seg.data.substr(_first_unassembled - new_seg.index, new_seg.length);new_seg.index = _first_unassembled;}_handle_overlap(new_seg);// if EOF was received before, it should remain valid_eof = _eof || eof_of_this_seg;
}void StreamReassembler::_handle_overlap(seg &new_seg) {for (auto it = _stored_segs.begin(); it != _stored_segs.end();) {auto next_it = ++it;--it;if ((new_seg.index >= it->index && new_seg.index < it->index + it->length) ||(it->index >= new_seg.index && it->index < new_seg.index + new_seg.length)) {_merge_seg(new_seg, *it);_stored_segs.erase(it);}it = next_it;}_stored_segs.insert(new_seg);
}void StreamReassembler::_stitch_output() {// _FIRST_UNASSEMBLED is the expected next index_FIRST_UNASSEMBLED// compare _STORED_SEGS.begin()->index with// if equals, then _STITCH_ONE_SEG() and erase this seg from set// continue compare until not equal or emptywhile (!_stored_segs.empty() && _stored_segs.begin()->index == _first_unassembled) {_stitch_one_seg(*_stored_segs.begin());_stored_segs.erase(_stored_segs.begin());}
}void StreamReassembler::_stitch_one_seg(const seg &new_seg) {// write string of NEW_SEG into _OUTPUT// update _FIRST_UNASSEMBLED_output.write(new_seg.data);_first_unassembled += new_seg.length;// both way of updating _FIRST_UNASSEMBLED is ok// _first_unassembled = _output.bytes_written();
}void StreamReassembler::_merge_seg(seg &new_seg, const seg &other) {size_t n_index = new_seg.index;size_t n_end = new_seg.index + new_seg.length;size_t o_index = other.index;size_t o_end = other.index + other.length;string new_data;if (n_index <= o_index && n_end <= o_end) {new_data = new_seg.data + other.data.substr(n_end - o_index, n_end - o_end);} else if (n_index <= o_index && n_end >= o_end) {new_data = new_seg.data;} else if (n_index >= o_index && n_end <= o_end) {new_data =other.data.substr(0, n_index - o_index) + new_seg.data + other.data.substr(n_end - o_index, n_end - o_end);} else{new_data = other.data.substr(0, n_index - o_index) + new_seg.data;}new_seg.index = n_index < o_index ? n_index : o_index;new_seg.length = (n_end > o_end ? n_end : o_end) - new_seg.index;new_seg.data = new_data;
}size_t StreamReassembler::unassembled_bytes() const {size_t unassembled_bytes = 0;for (auto it = _stored_segs.begin(); it != _stored_segs.end(); ++it)unassembled_bytes += it->length;return unassembled_bytes;
}bool StreamReassembler::empty() const { return unassembled_bytes() == 0; }

在这里插入图片描述

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

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

相关文章

CS144 lab2 笔记

CS144 lab2 笔记 介绍 在lab0中&#xff0c;我们实现了一个ByteStream。 在lab1中&#xff0c;实现了一个重组字符片段的StreamReassembler&#xff0c;重组收到的字符片段&#xff0c;并且将排序好的字符串退送到ByteStream 在lab2中&#xff0c;j将实现一个TCPReceiver,它…

CS144 计算机网络实验 lab3 笔记

CS144 计算机网络实验 lab3 笔记 介绍 本实验中,我们将会在之前实验的基础上,实现一个TCP sender ----将字节流转换成数据报并发送. TCP协议是一个在不可靠的协议上提供可靠的,流量控制的协议。 我们在本实验中会实现一个TCP发送端&#xff0c;负责将发送端应用层传入的比特…

CS144 lab4 计算机网络实验 笔记

CS144 lab4 计算机网络实验 笔记 介绍 本实验中,我们将组合TCP sender和TCP receiver实现一个完整的TCP connection TCP是全双工连接,所以两方可以同时接收/发送信息,一端随时都有可能接收.发送信息 主要根据上图实现 tcp_connection.cc #include "tcp_connection.hh&…

C# GDI+ 实现图片分隔

1. 概述 有时候我们需要在web页面上显示一张图&#xff0c;比如说一张地图&#xff0c;而这张地图会比较大。这时候如果我们把一张大图分隔成一组小图&#xff0c;那么客户端的显示速度会明显地感觉块。希望阅读本文对你有所帮助。 2. 实现思路 .NET Framework GDI 为我们提…

c/c++面试试题(一)

1.求下面函数的返回值&#xff08;微软&#xff09;int func(x) { int countx 0; while(x) { countx ; x x&(x-1); } return countx; } 假定x 9999。 答案&#xff1a;8思路&#xff1a;将x转化为2进制&#xff0c;看含有的1…

2. Get the codes from GIT

Clone the code from git. Click the “GitEx Clone”. Paste the url into the “Repository to clone”. You can get the route from git repository from it: https://msstash.companydomainname.com/ .Find the project which you want to download and then click the “…

The Ranges Library (2) --- C++20

The Ranges Library (2) — C20 比较std与std::ranges算法 比较一下std::sort和std::ranges::sort std::sort template< class RandomIt > constexpr void sort( RandomIt first, RandomIt last );template< class ExecutionPolicy, class RandomIt > void sor…

WPF中的动画

WPF中的动画 周银辉动画无疑是WPF中最吸引人的特色之一&#xff0c;其可以像Flash一样平滑地播放并与程序逻辑进行很好的交互。这里我们讨论一下故事板。在WPF中我们采用Storyboard&#xf…

[访问系统] Api_Win32_Mac类工具包 (转载)

点击下载 Api_Win32_Mac.zip using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices;namespace BaseFunction {class API{[DllImport("kernel32")]//内存public static extern void GlobalM…

constexpr 函数

constexpr 函数 — C 20 constexpr double pi 3.14;constexpr允许你在编译时使用典型的C函数语法进行编程,但这并不意味之constexpr只和编译期有关 constexpr函数可以在编译期运行,也可以在运行时运行 但在以下情况constexpr函数必须在编译期运行: constexpr函数在编译的上…

constexpr和consteval --- C++ 20

constexpr和consteval — C 20 标准库容器和算法库对constexpr 的应用 C20 中大量的算法和容器可以使用constexpr,这意味着你甚至可以再编译期vector<int>进行排序 Algorithms library - cppreference.com 如下: #include <iostream> #include <ranges>…

函数模板(参考《C++ Templates 英文版第二版》)

函数编程(参考《C Templates 英文版第二版》) Chapter 1 函数模板 1.1 一窥函数模板 template<class T> T max(T a, T b) {return b < a ? a : b; }#include "max1.hpp" #include <iostream> #include <string> #include <format>int…

Curiously Recurring Template Pattern奇怪的模板递归 --- C++20

Curiously Recurring Template Pattern 奇怪的模板递归 — C20 我们都知道C有静态多态和动态多态,动态多态通过虚函数表实现,他的缺点就是对效率产生一点点影响 可以用CRTP解决这个问题 我们先举一个动态多态的例子: #include <iostream> using namespace std;class …