CS144-Lab0解析

news2024/12/27 22:23:12

讲在开头

cs144建议我们使用Modern C++来完成所有的lab,关于modern c++的全面的用法可以在(http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines)获取。

以下是一些代码规范:

  • 不要使用malloc()free()
  • 不要使用newdelete
  • 在不得不使用指针时应使用智能指针(unique_ptr或者shared_ptr),而不是原始指针(*)
  • 避免使用模板、多线程、锁和虚函数
  • 避免使用C风格的类型转换(FILE)*x,必要时使用C++的static_cast
  • 避免使用C风格的字符串char *s,和C语言中的字符串函数strlen(), strcpy(),应使用c++中 std::string
  • 尽可能的使用常量引用(e.g.: const Address & address
  • 尽可能用const修饰变量和方法
  • 避免全局变量,尽可能缩小每个变量的作用域
  • 在提交之前,请使用make format来修改代码风格

在本次热身实验中,我们将会利用操作系统预先存在的接口来实现一个简单的TCP socket,并利用这个tcp socket来实现对网页的请求。

使用OS的流套接字写一个网络程序

这个部分比较简单,只需要按照handout所说,看完TCPSocket,FileDescriptor,Socket和Address这几个类的介绍,就能很快的完成这个程序,其实只需要看TCPSocket class就行。这些源代码都在libsponge\util中。

Inheritance graph

在linux系统中,一切皆文件。

webget.c

void get_URL(const string &host, const string &path) {
    TCPSocket tsk;
    tsk.connect(Address(host,"http"));

    tsk.write("GET " + path + " HTTP/1.1\r\n" +
                "Host: " + host + "\r\n" +
                "Connection: close\r\n\r\n");
    string str;
    while(!tsk.eof()) {
        tsk.read(str);
        cout << str;
    }

    tsk.close();
}

注意的是write的字符串要写成HTTP请求的格式,这也就是我们的应用层数据,在通过socket后会封装上TCP头部再丢进网络层传输。

内存中的可靠数据流

我们要完成的任务是实现一个类似于管道的数据结构ByteStream,这个channel有两端,一端是input side,负责向channel中输入字符串,另一端是output side,负责从channel中读取字符串并且取出来,在抽象的数据结构中来看,std::deque双端队列最合适不过。

这个管道是有容量限制的,其在初始化时就会规定好其capacity,作为在任意时刻channel内的最大字符量。随着output side对channel内字符串的读取,input side被允许写入更多的字符串,这意味着ByteStream可以传输比其自身capacity更大的数据,换句话就是ByteStream的容量理论上可以达到无限,只要input side持续地write。

在对ByteStream的功能熟悉后,我们就可以在libsponge\byte_stream.hhlibsonge\byte_stream.cc的骨架代码中完成我们的实现。这里需要特别强调一下**EOF的状态:** end of file是指在input side终止了输入的前提下,output side从channel中读取完了所有的字符串,此时ByteStream中的数据为空,并且不会再有数据输入。

对于ByteStream类,我添加的私有成员如下:

class ByteStream {
  private:
    // Your code here -- add private members as necessary.
    size_t _capacity;
    bool _eof = false;
    std::deque<char> _buffer;
    size_t _total_write;
    size_t _total_read;
    

    bool _error{};  //!< Flag indicating that the stream suffered an error.

  ...
}

ByteStream类的方法的实现:

ByteStream::ByteStream(const size_t capa) : _capacity(capa), _eof(false), _buffer(), _total_write(0), _total_read(0) {}

size_t ByteStream::write(const string &data) {
    size_t remain_size = _capacity - _buffer.size();
    size_t len = min(remain_size, data.length());
    for (size_t i = 0; i < len; i++)
        _buffer.push_back(data[i]);
    _total_write += len;
    return 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 l = min(len, _buffer.size());
    string output = "";
    for (size_t i = 0; i < l; i++)
        output += _buffer[i];

    return output;
}

//! \param[in] len bytes will be removed from the output side of the buffer
void ByteStream::pop_output(const size_t len) {
    size_t l = min(len, _buffer.size());
    _total_read += l;
    while (l--)
        _buffer.pop_front();
}

//! 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
std::string ByteStream::read(const size_t len) {
    string str = peek_output(len);
    pop_output(len);
    return str;
}

void ByteStream::end_input() { _eof = true; }

bool ByteStream::input_ended() const { return _eof; }

size_t ByteStream::buffer_size() const { return _buffer.size(); }

bool ByteStream::buffer_empty() const { return _buffer.empty(); }

bool ByteStream::eof() const { return _eof && _buffer.empty(); }

size_t ByteStream::bytes_written() const { return _total_write; }

size_t ByteStream::bytes_read() const { return _total_read; }

size_t ByteStream::remaining_capacity() const { return _capacity - _buffer.size(); }

通过下列指令完成编译;

mkdir build
cd build
cmake ..
make
make check_lab0

结果如下:

image-20221219011624614

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

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

相关文章

如何自动估算项目开发成本及报价,提高估算效率?

项目估算需要有科学专业的估算方法&#xff0c;需要有明确的量化指标&#xff0c;那么如何自动估算项目开发成本及报价&#xff1f; 第一步&#xff1a;功能点复杂程度的估算 CoCode需求分析工具&#xff0c;根据用户需求&#xff0c;使用COSMIC和IFPUG项目规模估算法&#xff…

数据结构C语言版 —— 队列+循环队列实现

文章目录队列1.概念2. 生活中队列应用3. 队列的实现初始化队列入队列出队列获取队头元素获取队尾元素获取队列中元素个数判断队列是否为空销毁队列2. 循环队列队列 1.概念 和栈相反&#xff0c;队列(queue)是一种先进先出的线性表&#xff0c;它只允许在一端进行插入&#xf…

C#-winform调用COM组件(COM组件由Qt开发)

一、场景介绍 在项目开发中,需要Qt与C#进行混合编程,完成项目开发。C#这边作为主框架,Qt负责编写插件,将功能模块通过COM组件的形式封装注册,再由C#调用、交互完成最终的项目。 程序开发环境: win10 64位 编译器: VS2017 Qt版本: Qt5.12.6 二、Qt封装COM组件 2.1 环境…

android flutter 安装

下载 flutter官网下载安装&#xff1a;https://flutter.dev/docs/development/tools/sdk/releases 将下载下来的zip安装包解压到想安装Flutter SDK的路径。注意&#xff0c;不要将flutter安装到需要一些高权限的路径&#xff0c;比如C:\Program Files\ 配置环境变量 添加fl…

案例教学 | 如何确定ADAMS简化模型的准确性,以及简化模型精度不够怎么办?

仿真建模过程中不可避免地对各种复杂元素进行简化处理。这种建模思路的终极目标是不牺牲仿真精度、还提升仿真效率。在Adams仿真建模过程中也有一些常见的简化方式&#xff0c;如非线性元素按线性建模、不考虑摩擦力、通过耦合约束等效传动关系等等。应用简化建模之前&#xff…

蓝桥杯有必要参赛吗?

昨天和群里的小伙伴在群里聊&#xff0c;有的小伙伴竟然说蓝桥杯一等奖没有含量&#xff0c;我也是醉了&#xff01; 就像去年看了一个号主写的&#xff1a;研究生遍地都是! 放眼全国14亿人口&#xff0c;别说研究生了&#xff0c;本科生占比有多少? “蓝桥杯是我人生中得到…

多态性:中的向下转型,instanceof 操作符的使用

多态性&#xff1a;中的向下转型&#xff0c;instanceof 操作符的使用 每博一文案 都说树叶不是一天变黄的&#xff0c;人心也不是一天变凉的&#xff0c;每一个现在的自己&#xff0c;其实都是过去的自己拼凑的。 如今我们的气质里都藏着过去走过的路&#xff0c;看过的书和爱…

混合模式和预乘原理的理解

首先说到混合模式&#xff0c;简单理解&#xff0c;混合模式就是同一像素上有两个颜色需要混合成一个使用的模式。 这里的两个像素点&#xff0c;我们把原先已经存在的&#xff0c;也就是下面的像素点颜色定义为目标颜色。把新加上来的&#xff0c;也就是上面的像素点颜色定义为…

【Selenium IDE录制脚本】三分钟教会你安装Selenium IDE的安装及使用

目录 1、安装Selenium IDE 1.1、安装Firefox浏览器 1.2、安装selenium IDE 2、selenium的脚本录制 1、安装Selenium IDE 1.1、安装Firefox浏览器 因为selenium的不同版本对Firefox的支持不同&#xff0c;所以我们安装了Firefox之后&#xff0c;需要关闭他的自动更新 搜索&…

Python-Tinydb数据库详解

目录 数据库 Tinydb Tinydb 使用 安装 导入 创建数据库 创建 table 增 删 查 改 其他函数 示例 最后 数据库 数据库就是存储数据的的地方&#xff0c;现在我们生活中几乎每时每刻做的事可能都有它的作用。今天来介绍 Tinydb 数据库&#xff0c;它适合初学者&am…

设计模式概述之建造者模式(五)

常说的设计模式是23种设计模式&#xff0c;分为3大类&#xff1a; 创建型模式5种&#xff1a;工厂方法、抽象工厂、单例、建造者、原型 结构型模式7种&#xff1a;适配器、代理、桥接、装饰者、外观、享元、组合 行为型模式11种&#xff1a;模板方法、解释器、策略、观察者、…

【如意如意顺遂我意快快显灵】

文章目录 ● 【猿如意安装】 &#xff08;基于Windows环境安装&#xff09; ● 【猿如意首页】 ● 【猿如意效率工具】 ● 【猿如意开发工具】 ● 【猿如意教程文档】 ● 【猿如意一行代码】 ● 【猿如意ChatGPT】 ● 【Markdown笔记】 猿如意官网&#xff1a;猿…

【码极客精讲】二叉树

二叉树&#xff08;Binary tree&#xff09;是树形结构的一个重要类型。许多实际问题抽象出来的数据结构往往是二叉树形式&#xff0c;即使是一般的树也能简单地转换为二叉树&#xff0c;而且二叉树的存储结构及其算法都较为简单&#xff0c;因此二叉树显得特别重要。二叉树特点…

Linux yum 命令

yum&#xff08; Yellow dog Updater, Modified&#xff09;是一个在 Fedora 和 RedHat 以及 SUSE 中的 Shell 前端软件包管理器。 基于 RPM 包管理&#xff0c;能够从指定的服务器自动下载 RPM 包并且安装&#xff0c;可以自动处理依赖性关系&#xff0c;并且一次安装所有依赖…

Go 微服务开发框架 DMicro 的设计思路

Go 微服务开发框架 DMicro 的设计思路 DMicro 源码地址: Gitee:dmicro: dmicro是一个高效、可扩展且简单易用的微服务框架。包含drpc,dserver等 背景 DMicro 诞生的背景&#xff0c;是因为我写了 10 来年的 PHP&#xff0c;想在公司内部推广 Go, 公司内部的组件及 rpc 协议都…

Python:whl文件简介及实践

文章目录简介一、安装过程二、whl源地址推荐小结简介 WHL文件是以Wheel格式保存的Python安装包&#xff0c;Wheel是Python发行版的标准内置包格式。在本质上是一个压缩包&#xff0c;WHL文件中包含了Python安装的py文件和元数据&#xff0c;以及经过编译的pyd文件&#xff0c;…

【视觉高级篇】27 # 如何实现简单的3D可视化图表:GitHub贡献图表的3D可视化?

说明 【跟月影学可视化】学习笔记。 第一步&#xff1a;准备要展现的数据 可以使用这个生成数据&#xff1a;https://github.com/sallar/github-contributions-api 这里直接使用月影大佬的github提交数据的数据即可 结构大致如下&#xff1a; 第二步&#xff1a;用 SpriteJS…

黑*头条_第6章_kafka及异步通知文章上下架

黑*头条_第6章_kafka及异步通知文章上下架 文章目录黑*头条_第6章_kafka及异步通知文章上下架1)自媒体文章上下架2)kafka概述3)kafka安装配置4)kafka入门5)kafka高可用设计5.1)集群5.2)备份机制(Replication&#xff09;6)kafka生产者详解6.1)发送类型6.2)参数详解7)kafka消费者…

小林Coding阅读笔记:操作系统篇之硬件结构,CPU Cache一致性问题

前言 参考/导流&#xff1a; 小林coding-2.4 CPU 缓存一致性学习意义 底层基础知识&#xff0c;了解CPU执行过程&#xff0c;让上层编码有效并发控制底层设计思维&#xff08;对比 MySQL的并发控制&#xff09;、更好地去理解JUC的锁、volatile以及JMM架构层面的一致性保证问…

毕业设计 单片机便携式空气质量检测仪 - 物联网 嵌入式

文章目录0 前言1 简介2 主要器件3 实现效果4 设计原理5 部分核心代码5 最后0 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题目缺少创新和亮点&#xff0c;往往达不到毕业答辩的要求&#xff0c;这两年不断有学弟学妹告诉学长…