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,一经查实,立即删除!

相关文章

Netty 4.0 新的特性及需要注意的地方

Netty 4.0 新的特性及需要注意的地方 这篇文章和你一起过下Netty的主发行版本的一些显著的改变和新特性&#xff0c;让你在把你的应用程序转换到新版本的时候有个概念。 项目结构改变 Netty的包名从org.jboss.netty改为io.netty&#xff0c;因为我们不在是JBoss.org的一部分了。…

CS144 lab2 笔记

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

附件下载,中文文件名乱码如何解决???

问:我写了个程序&#xff0c;里面有文件要作为附件下载&#xff0c;英文文件名都正常&#xff0c;但中文文件名就会乱码&#xff0c;不知道如何解决&#xff0c;望高手指点。代码如下&#xff1a;&#xff1d;&#xff1d;&#xff1d;&#xff1d;&#xff1d;&#xff1d;&am…

养生之道

晚上 9-11点为免疫系统&#xff08;淋巴&#xff09;排毒时间&#xff0c;此段时间应安静或听音乐 晚间 11-凌晨 1点&#xff0c;肝的排毒&#xff0c;需在熟睡中进行。 凌晨 1-3点&#xff0c;胆的排毒&#xff0c;亦同。 凌晨 3-5点&#xff0c;肺的排毒。此即为何咳嗽的人…

freemarker小例子

1.在D盘下创建一个目录D:\\freemarker 2.在以上目录中放入一个模板文件test.ftl,内容如下&#xff1a; 第一个测试程序&#xff1a;${abc} 3.java代码如下&#xff08;需要导入freemarker.jar包&#xff09; Java代码 : package cn.freeteam.util;import java.io.BufferedW…

CS144 计算机网络实验 lab3 笔记

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

发送附件时,防止文件名中的中文字符变成乱码

在.net2005中&#xff0c;利用System.Net.Mail;下的MailMessage类发送邮件&#xff0c;为了防止附件文件名中的中文字符变成乱码&#xff0c;需要加attachment.NameEncoding Encoding.GetEncoding("GB2312");详细见下面的函数&#xff1a; private bool SendMail(s…

React(77)--纯函数和非纯函数

let student {firstName: "testing",lastName: "testing",marks: 500 }// 非纯函数 function appendAddress() {student.address {streetNumber:"0000", streetName: "first", city:"somecity"}; }console.log(appendAddr…

计算机进程小知识

最基本的系统进程&#xff08;也就是说&#xff0c;这些进程是系统运行的基本条件&#xff0c;有了这些进程&#xff0c;系统就能正常运行&#xff09;: smss.exe Session Manager csrss.exe 子系统服务器进程 winlogon.exe 管理用户登录 services.exe 包含很多系统服务 lsass.…

CS144 lab4 计算机网络实验 笔记

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

unity2D技术学习与整理

目前有关unity2D的教程以及原理几乎都是国外的。我在这方面也是新手&#xff0c;看了一些例子有很多不懂的地方。 这个网站提供的教程很有参考价值 http://brackeys.com/ 还有这个 http://pixelnest.io/tutorials/2d-game-unity/table-of-contents/转载于:https://www.cnblogs.…

C# GDI+ 实现图片分隔

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

让人吐血的文章,要被气死了

来源&#xff1a;[url]http://dx.3800hk.com/news/w21/124454.html[/url]请注意文中这两部分新世纪&#xff1a;为什么在李俊落网之前&#xff0c;很多人都怀疑这是杀毒软件公司的人干的&#xff0c;目的是为了多卖几套杀毒软件&#xff1f;李铁军&#xff1a;人们一直都有这种…

共享锁和排它锁---C++17 多线程

共享锁和排它锁—C17 多线程 读写锁把对共享资源的访问者划分成读者和写者&#xff0c;读者只对共享资源进行读访问&#xff0c;写者则需要对共享资源进行写操作。C17开始&#xff0c;标准库提供了shared_mutex类&#xff08;在这之前&#xff0c;可以使用boost的shared_mutex…

将人民币的数字表示转化成大写表示(C#版)

using System; namespace Test.Com{ /// <summary> /// 功能&#xff1a;字符串处理函数集 /// </summary> public class DealString { #region 私有成员 /// <summary> /// 输入字符串 /// </summary> private string inputStringnull; /// <…

C#图片切割

图片切割就是把一幅大图片按用户要求切割成多幅小图片。dotnet环境下系统提供了GDI类库&#xff0c;为图像操作处理提供了方便的接口。 下面是图像切割小程序&#xff1a; public class ImageManager { /// <summary> /// 图像切割 /// </s…

条件变量 ---C++17 多线程

条件变量 —C17 多线程 C标准库提供了条件变量的两种实现&#xff1a;std::condition_variable 和std::condition_variable_any。它们都在标准库的头文件<condition_variable>内声明。两者都需配合互斥&#xff0c;方能提供妥当的同步操作。std::condition_variable仅限…