【斯坦福计网CS144项目】环境配置 Lab0: ByteStream
前言
感觉学了不少 C++ 编程的知识和技术但比较缺少实践,于是打算找一些项目跟着做一做。
首先安利一个自学网站 CS自学指南,北大的同学做的,汇总了很多国内外高校 CS 相关的高质量公开课,其中大部分是有课程项目的。翻了翻感觉 Stanford 的这门 CS144 计网课的 Lab 比较有趣,难度也不错,就是它了!
课程网址:CS 144: Introduction to Computer Networking
我跟的是 2021 Fall 学期的版本。
我的 Github 项目:CS144-Lab,7个实验的完成版代码位于 libsponge/
文件夹内。
准备工作
在上面的网站中先把 8 个实验的文档(红框)下载下来,然后按上图中 Virtual machine setup instructions 链接开始设置虚拟机环境。推荐使用方法一:VirtualBox + 课程组准备好的 Ubuntu 镜像,跟着这个链接的步骤做就可以。设置共享文件夹那步建议完成。
完成后得到的是一个控制台界面的 Ubuntu 18.04 系统。该虚拟机已经设置好可以通过ssh连接(localhost:2222 端口),为了方便开发,可以用 PuTTY 连接打开多个窗口,配置如下(建议保存成 session,每次直接加载):
因为没有图形界面,开发工具自然是用 Vim,如果对 Vim 操作不熟练(比如博主自己ww)正好是个不错的锻炼机会。如果完全没有接触过 Vim,可以看 MIT 的 Missing Semester 中 Editors (Vim) 这课入门。关于 Vim 环境的配置,个人还是比较建议装一些插件(如语法高亮、代码补全等)改善开发体验,我的 .vimrc 如下,主要使用了 Vundle 插件管理,Molokai 主题,YouCompleteMe 代码分析补全还有 Vim 自带的显示行号等基本功能。Vim 的很多插件可以在这个网站上淘到。如果有需要以后也可以写一篇文章记录这个配置过程。
Lab 0
因为计网的知识大三都学过,做完以上准备工作就可以愉快地开始实验了。Lab 0 的第二部分 Networking by hand 和第三部分 Writing a network program using an OS stream socket 都比较简单,跟着文档说明一步步做就好,这里直接看第四部分 An in-memory reliable byte stream。
本节要求我们实现一个可靠的字节流(Byte Stream)类,reader/writer 分别能够从一端读出数据,一端写入数据,同时要控制流中数据任意时刻不能超过某个容量(capacity)值。这里无需考虑多线程使用读写锁等问题。需要实现的 public 函数已经定义好,实现时可以补充任意私有成员。
待完成的代码在 sponge/libsponge 目录内,完成后在 sponge/build 目录中执行 make (-j4/-j8)
编译,然后执行 make check_lab0
以运行自动测试,如果看到 100% tests Passed
则说明通过(t_webget
需要连接国外网站,耗时较长或超时都没关系)。如果需要运行单个测试,执行 ctest -R 测试名
,测试名就是运行所有测试时输出的 Test #1: t_xx
中的 t_xx
,然后根据提示信息可以查看单次测试的输出日志(注意:如果要用打印语句 Debug,用 cerr
而不是 cout
输出)。以后的实验都是如此,不再重复。
回到本次任务,要求还是比较简单的,选用一个数据结构存储数据流并维护一些状态信息即可,我这里用的是 deque<char>
。容器的操作等实现细节上注意尽量用 Modern C++ 的风格。
ByteStream.hh:
#ifndef SPONGE_LIBSPONGE_BYTE_STREAM_HH
#define SPONGE_LIBSPONGE_BYTE_STREAM_HH#include <deque>
#include <string>//! \brief An in-order byte stream.//! Bytes are written on the "input" side and read from the "output"
//! side. The byte stream is finite: the writer can end the input,
//! and then no more bytes can be written.
class ByteStream {private:// Your code here -- add private members as necessary.// Hint: This doesn't need to be a sophisticated data structure at// all, but if any of your tests are taking longer than a second,// that's a sign that you probably want to keep exploring// different approaches.std::deque<char> _buf{};std::size_t _capacity;std::size_t _bytes_written = 0;std::size_t _bytes_read = 0;bool _input_ended = false;bool _error = false; //!< Flag indicating that the stream suffered an error.public://! Construct a stream with room for `capacity` bytes.ByteStream(const size_t capacity);//! \name "Input" interface for the writer//!@{//! Write a string of bytes into the stream. Write as many//! as will fit, and return how many were written.//! \returns the number of bytes accepted into the streamsize_t write(const std::string &data);//! \returns the number of additional bytes that the stream has space forsize_t remaining_capacity() const;//! Signal that the byte stream has reached its endingvoid end_input();//! Indicate that the stream suffered an error.void set_error() { _error = true; }//!@}//! \name "Output" interface for the reader//!@{//! Peek at next "len" bytes of the stream//! \returns a stringstd::string peek_output(const size_t len) const;//! Remove bytes from the buffervoid pop_output(const size_t len);//! Read (i.e., copy and then pop) the next "len" bytes of the stream//! \returns a stringstd::string read(const size_t len);//! \returns `true` if the stream input has endedbool input_ended() const;//! \returns `true` if the stream has suffered an errorbool error() const { return _error; }//! \returns the maximum amount that can currently be read from the streamsize_t buffer_size() const;//! \returns `true` if the buffer is emptybool buffer_empty() const;//! \returns `true` if the output has reached the endingbool eof() const;//!@}//! \name General accounting//!@{//! Total number of bytes writtensize_t bytes_written() const;//! Total number of bytes poppedsize_t bytes_read() const;//!@}
};#endif // SPONGE_LIBSPONGE_BYTE_STREAM_HH
ByteStream.cc:
#include "byte_stream.hh"using namespace std;ByteStream::ByteStream(const size_t capacity) : _capacity(capacity) {}size_t ByteStream::write(const string &data) {if (_input_ended) {return 0;}size_t write_len = min(data.size(), remaining_capacity());_buf.insert(_buf.end(), data.begin(), data.begin() + write_len);_bytes_written += write_len;return write_len;
}//! \param[in] len bytes will be copied from the output side of the buffer
string ByteStream::peek_output(const size_t len) const {size_t peeked_len = min(len, _buf.size());return string(_buf.begin(), _buf.begin() + peeked_len);
}//! \param[in] len bytes will be removed from the output side of the buffer
void ByteStream::pop_output(const size_t len) {size_t popped_len = min(len, _buf.size());_buf.erase(_buf.begin(), _buf.begin() + popped_len);_bytes_read += popped_len;
}//! Read (i.e., copy and then pop) the next "len" bytes of the stream
//! \param[in] len bytes will be popped and returned
//! \returns a string
string ByteStream::read(const size_t len) {if (len == 0) {return "";}string res = peek_output(len);pop_output(res.size());return res;
}void ByteStream::end_input() { _input_ended = true; }bool ByteStream::input_ended() const { return _input_ended; }size_t ByteStream::buffer_size() const { return _buf.size(); }bool ByteStream::buffer_empty() const { return _buf.empty(); }bool ByteStream::eof() const { return input_ended() && buffer_empty(); }size_t ByteStream::bytes_written() const { return _bytes_written; }size_t ByteStream::bytes_read() const { return _bytes_read; }size_t ByteStream::remaining_capacity() const { return _capacity - _buf.size(); }
最后贴张通关图
【斯坦福计网CS144项目】环境配置 Lab0: ByteStream相关推荐
- Vue第七章:项目环境配置及单文件组件 vue脚手
第七章:项目环境配置及单文件组件 vue脚手架 回顾: 组件之间的通信 父传子:正向传递 vue允许 自动触发 props 1.先在子组件中定义期待的属性名和类型 2.在父组件中调用子组件 ...
- 【java】项目环境配置
项目环境配置 一.SVN 版本控制 1. 下载安装 2. Checkout同步代码 3. Update更新代码 4. Commit提交代码 5. 撤销本地修改 6. 查看提交记录 二.IntellJ ...
- 【持续集成和交付】项目环境配置:在Jenkins中运行项目
前言 一直想学习自动化测试,但是都没行动,业余时间学习零零碎碎并记录20210424. 11.持续集成和交付 Jenkins环境搭建 项目环境配置 邮件通知 定时项目执行 在Jenkins中运行项目 ...
- Python人脸识别项目-环境配置
环境配置 首先我们需要需要配置所需的环境,作者使用的编译器是Pycharm,在安装失败多次情况下(不知道为什么我Pycharm上装有问题),我发现了最简单的配置方法.首先在工作台中输入以下命令进行安装 ...
- Vue项目环境配置(尚硅谷笔记)
文章目录 Vue3项目继承 一.项目集成 3.1集成element-plus 3.2src别名的配置 3.3环境变量的配置 3.4SVG图标配置 3.4.1svg封装为全局组件 3.5集成sass 3 ...
- java的jdk安装教程附百度网盘链接环境配置遇到的各种问题版本选择
首先关于JDK版本的选择–附百度网盘链接 现在互联网行业各家公司大部分使用的是jdk8.0(也被叫做jdk1.8,有兴趣的话可以去百度以下jdk演变历史)虽然现在jdk更新到11版本了,但是不建议使用 ...
- 【SLAM】——DynaSLAM项目环境配置(超多坑)
DynaSLAM 坑多,慢慢来,不要急 先整体说一下,项目是在ORB-SLAM2项目的基础上,加上maskrcnn的融合.主流程采用还是采用ORB-SLAM2的流程,maskrcnn部分采用c++调用 ...
- 前端——vue项目环境配置
node类似一个浏览器,npm是包管理器. 搞node的开发者不想维护node了,所以把node交给了好友npm开发者,这个npm开发者就把两个搞一起去了.. 我们配置java环境的流程是下载jdk, ...
- vscode安装使用,开发python项目环境配置
# 一.vscode设置python解释器 1.使用vscode添加需要的插件在扩展商店汉化chinese进行python开发python 完成汉化以及提示补全django用到的Git history ...
最新文章
- 为了鉴别世界名画,我死磕CNN后终于搭建了自己的模型
- 二叉树的概念、算法简介及树的平衡
- 【javascript 对日期的扩展 Format\addDays】
- 黑马程序员 Python学习笔记之 程序执行原理(科普)
- IPQ4019 QSDK 下添加RM500Q 5G 驱动 qmi拨号链接网络 配置 IPK包方法
- Terminal终端命令(全)
- 咸鱼笔记:《实用软件工程》第一、二章课后简答题及参考答案
- 开机bat脚本解决steam无法自动登陆
- android黑科技系列——手机端破解神器MT的内购VIP功能破解教程
- 《现代汉语》北大公开课
- python土味情话_GitHub - MMstarry/itchat: 微信机器人 土味情话
- 枚举证书和 CAPI读取证书总结
- 搜狗输入法 - 自定义短语
- MATLAB函数大全 .
- 装饰模式 - Unity
- Ubuntu定时开关机
- ysdk接入,支付提示:系统繁忙,请稍后再试 (1003-498686-498686)
- Android官网教你如何系统学习
- service饬令用于经管Linux把持系统中效劳的饬令
- 读《区块链革命 》有感