CS144 - LAB0
CS144 - Lab 0
telnet 发送请求
如图,很简单,但是注意输入时间太久会超时
发邮箱
首先我们需要用命令行去发邮箱,这里我用企业微信邮箱给自己的 qq 邮箱发送~
整个命令如下!
对于其中的参数,其实从英文就可以看出来,首先连接到企业微信邮箱的发送邮箱的服务器,然后输入 HELO smtp.exmail.qq.com 表示开始进行和 smtp 服务器的会话,然后我们可以输入 AUTH LOGIN 来鉴权,首先输入你的邮箱的对应的 base64 的编码,比如我的邮箱是 rinai@g-rinai.cn 就将他转换为 base64 编码就可以了,然后我们还需要一个登录密码,注意,这个密码虽然也需要 base64 编码,但是并不是需要你的登录密码,而是一个密钥,基本每个邮箱客户端都会有这样一个位置给我们提供这样一个密钥,比如我是企业微信邮箱,获取密钥的位置在这里:
点击生成新密码,然后把对应的密码输入到 base64 编码器即可,注意,如果你的码暴露给别人了,请及时删除,比如我现在用完就删了😇
然后鉴权成功,我们可以输入发送方,接收方,输入内容,然后输入 “换行” + “.” 就可以结束了。
结果是成功发送,通过这个方法,你可以给别人发邮件😍😍😍,那么,Next。
netcat 启动服务器
我们可以使用 netcat -v -l -p 9090
在本地启动一个服务器,端口为 9090,我们在另一个窗口可以通过 telnet localhost 9090 来连接本地的这个服务器。
编写 webget
这里就是真正涉及到代码了,我们需要用套接字实现我们刚刚第一个 telnet 发送请求的功能,这里感觉并不是很难,就是我对套接字编程不太熟悉,很多系统调用都不知道😭,然后我去看了一下 linux 高性能服务器编程里面的套接字编程,就看了几个 API 就写出来了,哈哈。
我们首先通过 gethostbyname
来获取域名对应的 ip 信息,然后创建一个套接字,并与对应的 ip 建立连接,发送我们的请求的内容,这里很简单,就是我们刚刚 telnet 之后写的内容,只需要注意一下换行符就可以了,然后从套接字里面循环读取数据到缓冲区并打印就可以了!
void get_URL(const string& host, const string& path)
{cerr << "Function called: get_URL(" << host << ", " << path << ")\n";// 通过域名解析获取 ipstruct hostent *server = gethostbyname(host.c_str());if (server == NULL) {cerr << "Error: Could not get host information for " << host << "\n";return;}// 这是一个用来表示 ipv4 地址信息的结构体// 用于套接字编程struct sockaddr_in server_addr;// 填充这个结构体server_addr.sin_family = AF_INET;server_addr.sin_addr.s_addr = *(u_long*)server->h_addr_list[0];server_addr.sin_port = htons(80);// 本地创建一个套接字int sockfd = socket(AF_INET, SOCK_STREAM, 0);if ( sockfd < 0 ) {cerr << "Error: Could not create socket\n";return;}// 连接到远程服务器if (connect(sockfd, (struct sockaddr*) &server_addr, sizeof(server_addr)) < 0 ) {cerr << "Error: Could not connect to server\n";return;}string request = "GET " + path + " HTTP/1.1\r\nHost: " + host + "\r\nConnection: close\r\n\r\n";if (send(sockfd, request.c_str(), request.size(), 0) < 0) {cerr << "Error: Could not send request\n";return;}char buffer[1024];int bytes_read = 0;while ((bytes_read = recv(sockfd, buffer, sizeof(buffer), 0)) > 0 ) {write(1, buffer, bytes_read);}if (bytes_read < 0) {cerr << "Error: Could not read response\n";return;}close(sockfd);
}
结果如下:
root@r-linux:/home/rinai/project/CS144# cmake --build build --target check_webget
Test project /home/rinai/project/CS144/buildStart 1: compile with bug-checkers
1/2 Test #1: compile with bug-checkers ........ Passed 0.20 secStart 2: t_webget
2/2 Test #2: t_webget ......................... Passed 1.10 sec100% tests passed, 0 tests failed out of 2Total Test time (real) = 1.30 sec
Built target check_webget
内存可靠字节流
这里很简单,就是写一个读写缓冲区模型,其实跟咱消费者生产者模型还是挺像的哈,主要就是一个缓冲区的状态管理,这里我不太熟悉 cpp 的生态,这里直接用了 string 类型来表示字节流了。
我的实现:
首先我们需要查看注释,为所谓的 bytestream 类添加成员字段:
class ByteStream
{
public:explicit ByteStream( uint64_t capacity );// Helper functions (provided) to access the ByteStream's Reader and Writer interfacesReader& reader();const Reader& reader() const;Writer& writer();const Writer& writer() const;void set_error() { error_ = true; }; // Signal that the stream suffered an error.bool has_error() const { return error_; }; // Has the stream had an error?protected:// Please add any additional state to the ByteStream here, and not to the Writer and Reader interfaces.uint64_t capacity_;bool error_ {};// added state:std::string buffer_; uint64_t read_cnt_;uint64_t write_cnt_;bool closed_ {};
};
然后我们需要为 Writer 和 Reader 实现构造函数和对应的读写方法。
#include "byte_stream.hh"using namespace std;ByteStream::ByteStream( uint64_t capacity ): capacity_(capacity),buffer_(), read_cnt_(0),write_cnt_(0)
{
}
void Writer::push( string data )
{if (Writer::is_closed()) return;Writer::write_cnt_ += min(Writer::available_capacity(), data.size());Writer::buffer_.append( data );Writer::buffer_.resize( min(Writer::buffer_.size(), capacity_) );return;
}void Writer::close()
{Writer::closed_ = true;
}bool Writer::is_closed() const
{return Writer::closed_;
}uint64_t Writer::available_capacity() const
{return capacity_ - Writer::buffer_.size();
}uint64_t Writer::bytes_pushed() const
{return Writer::write_cnt_;
}string_view Reader::peek() const
{std::string_view view(Writer::ByteStream::buffer_.data(), Writer::ByteStream::buffer_.size());return view;
}void Reader::pop( uint64_t len )
{if (Reader::is_finished())return;if (len > Reader::bytes_buffered())return;printf("before buffer size: %lu\n", Reader::buffer_.size());Reader::buffer_.erase(0, len);printf("after buffer size: %lu\n", Reader::buffer_.size());Reader::read_cnt_ += len;return;
}bool Reader::is_finished() const
{return Reader::closed_ && Reader::buffer_.empty();
}uint64_t Reader::bytes_buffered() const
{return Reader::buffer_.size();
}uint64_t Reader::bytes_popped() const
{return Reader::read_cnt_;
}
写的时候也需要熟悉一下 cpp 的语法了,感觉这种面向对象的结构还挺新鲜的,跟 go 的结构完全不一样。
最后:
root@r-linux:/home/rinai/project/CS144# cmake --build build --target check0
Test project /home/rinai/project/CS144/buildStart 1: compile with bug-checkers1/11 Test #1: compile with bug-checkers ........ Passed 0.85 secStart 2: t_webget2/11 Test #2: t_webget ......................... Passed 1.27 secStart 3: byte_stream_basics3/11 Test #3: byte_stream_basics ............... Passed 0.02 secStart 4: byte_stream_capacity4/11 Test #4: byte_stream_capacity ............. Passed 0.01 secStart 5: byte_stream_one_write5/11 Test #5: byte_stream_one_write ............ Passed 0.01 secStart 6: byte_stream_two_writes6/11 Test #6: byte_stream_two_writes ........... Passed 0.02 secStart 7: byte_stream_many_writes7/11 Test #7: byte_stream_many_writes .......... Passed 0.10 secStart 8: byte_stream_stress_test8/11 Test #8: byte_stream_stress_test .......... Passed 0.03 secStart 37: no_skip9/11 Test #37: no_skip .......................... Passed 0.01 secStart 38: compile with optimization
10/11 Test #38: compile with optimization ........ Passed 3.15 secStart 39: byte_stream_speed_testByteStream throughput (pop length 4096): 11.88 Gbit/sByteStream throughput (pop length 128): 2.13 Gbit/sByteStream throughput (pop length 32): 0.56 Gbit/s
11/11 Test #39: byte_stream_speed_test ........... Passed 0.36 sec100% tests passed, 0 tests failed out of 11Total Test time (real) = 5.84 sec
Built target check0
clear
相关文章:

CS144 - LAB0
CS144 - Lab 0 telnet 发送请求 如图,很简单,但是注意输入时间太久会超时 发邮箱 首先我们需要用命令行去发邮箱,这里我用企业微信邮箱给自己的 qq 邮箱发送~ 整个命令如下! 对于其中的参数,其实从英文就可以看出来…...

论文浅尝 | 将复杂知识图谱问答对齐为约束代码生成(COLING2025)
笔记整理:康家溱,东南大学在读硕士,研究方向为代码大语言模型 论文链接:https://aclanthology.org/2025.coling-main.267.pdf 发表会议:COLING 2025 1. 动机 近年来,随着大语言模型(LLM…...
【Linux命令】scp远程拷贝
文章目录 1. 基本语法与常用选项2. 使用场景和使用示例本地文件->远程主机远程主机文件->本地远程主机->另一台远程主机 3. 使用注意事项 scp(Secure Copy Protocol)是linux中基于ssh的安全文件传输工具,用于在本地和远程主机之前安…...

Golang|分布式搜索引擎中所使用到的设计模式
迭代器模式 定义:在遍历接口时,提供统一的方法函数供调用,保持一致性。核心思想:与大众习惯保持一致,方便第三方实现容器类时保持一致。常见方法:如next()方法,适用于所有集合类,简化…...

Ubuntu22.04通过命令行安装qt5
环境: VMware17Pro ubuntu-22.04.5-desktop-amd64.iso 步骤: 安装好虚拟机进入shell,或通过ssh登录,确保虚拟机能上外网,执行命令: sudo apt update sudo apt install build-essential sudo snap in…...
【仿生机器人】仿生机器人系统架构设计2.0——具备可执行性
结合我的需求后,来自Claude4.0 的结构设计 仿生机器人系统架构设计 一、系统总体架构 1.1 核心设计理念 涌现式情感:情感不是预设的规则,而是从环境感知、记忆关联和内在状态的复杂交互中涌现出来动态人格塑造:性格特质随着经…...

STM32:ESP8266 + MQTT 云端与报文全解析
知识点1【MQTT的概述】 1、概述 MQTT是一种基于发布/订阅模式的轻量级应用层协议,运行在TCP/IP协议之上,专用物联网(IoT)和机器对机器(M2M)设计,其核心目标是低带宽,高延迟或不稳定…...

HTML5 Canvas 星空战机游戏开发全解析
HTML5 Canvas 星空战机游戏开发全解析 一、游戏介绍 这是一款基于HTML5 Canvas开发的2D射击游戏,具有以下特色功能: 🚀 纯代码绘制的星空动态背景✈️ 三种不同特性的敌人类型🎮 键盘控制的玩家战机📊 完整的分数统…...

箱式不确定集
“箱式不确定集(Box Uncertainty Set)”可以被认为是一种 相对简单但实用的不确定集建模方式。 ✅ 一、什么是“简单的不确定集”? 在鲁棒优化领域,“简单不确定集”通常指的是: 特点描述形式直观数学表达简洁&#…...

内存管理 : 04段页结合的实际内存管理
一、课程核心主题引入 这一讲,我要给大家讲的是真正的内存管理,也就是段和页结合在一起的内存管理方式。之前提到过,我们先学习了分段管理内存的工作原理,知道操作系统采用分段的方式,让用户程序能以分段的结构进行编…...
不使用绑定的方法
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); // 初始设置 A 控件的宽度 ControlA.Width ControlB.Width / 2; // 监听 B 控件的 SizeChanged 事件 ControlB.SizeChanged (sender, e) > { ControlA.Width ControlB.Actual…...
Spring Boot 中的 Web 应用与 Reactive Web 应用
该判断题表述为:“Spring Boot启动过程中会判断当前应用类型是Web应用还是Reactive Web应用。” 这个说法是 正确的。Spring Boot 的自动配置机制会检查类路径,以确定是将应用程序配置为传统的 Servlet Web 应用还是 Reactive Web 应用。 Spring Boot 中…...
基于 stm32 的农用车控制系统设计
一、系统功能需求分析 农用车控制系统需实现多方面功能,以满足农业生产多样化需求。在动力控制方面,要实现发动机转速调节、挡位自动切换;作业控制涵盖农机具升降、播种施肥量调节、喷洒农药的流量与压力控制等;同时,还需具备车辆状态监测功能,实时监控发动机温度、油压…...

vue3: baidusubway using typescript
项目结构: <!--npm install -D tailwindcss-3d BaiduSubwayMap.vue npm install -D tailwindcss postcss autoprefixer--> <template><div class"relative w-full h-screen"><!-- 地图容器 --><div id"subway-container…...

Redis最佳实践——性能优化技巧之集群与分片
Redis集群与分片在电商应用中的性能优化技巧 一、Redis集群架构模式解析 1. 主流集群方案对比 方案核心原理适用场景电商应用案例主从复制读写分离数据冗余中小规模读多写少商品详情缓存Redis Sentinel自动故障转移监控高可用需求场景订单状态缓存Redis Cluster原生分布式分片…...
vue或者前端适配makedown推荐开源依赖
在 Vue 或前端项目中处理 Markdown 格式,以下是一些推荐的开源依赖和工具,根据需求分类整理: 1. 基础 Markdown 解析与渲染 Vue 专用库 vueuse/markdown VueUse 生态的 Markdown 工具,轻量且集成度高。 适合快速在 Vue 项目中渲…...
打打基础 | 从翻转链表到寄存器、汇编与内存
我作为软件工程师在美国工作了三年,期间接触和浸泡过不少的技术栈,罗列一番的话有 AWS cloud, frontend (React, TypeScript), backend (Django, Springboot, ECS, GraphQL), JVM (Java, Scala, Kotlin), data pipelines (Spark, Snowflake, Prefect, DB…...
深入解析 Dotnet-Boxed.Framework:提升 .NET 开发效率的利器
在现代 .NET 开发中,框架和工具的选择对项目的开发效率和长期维护至关重要。Dotnet-Boxed.Framework 是一个开源框架,旨在简化开发流程,提高生产力。它通过一组实用的工具和自动化功能,帮助开发者快速构建高质量的应用程序。本文将…...

常见相机的ISP算法
常见的ISP算法 3A算法 去雾算法 图像增强算法 图像宽动态算法 图像的电子缩放算法,无极电子缩放 图像降噪算法 相机常见问题 1.相机启动速度问题,启动速度较慢 2.相机扛不住高低温问题 3.相机散热问题问题 4.相机高低温芯片保护掉电 5.相机的成像效果或者…...

2024 CKA模拟系统制作 | Step-By-Step | 8、题目搭建-创建 Ingress
目录 免费获取题库配套 CKA_v1.31_模拟系统 一、题目 二、核心考点 Ingress 资源定义 Ingress Controller 依赖 服务暴露验证 网络层次关系 三、搭建模拟环境 1.创建命名空间 2.安装ingress ingress-nginx-controller 3.创建hello.yaml并部署 四、总结 …...

OldRoll复古胶片相机:穿越时光,定格经典
在数字摄影盛行的今天,复古胶片相机的独特魅力依然吸引着无数摄影爱好者。OldRoll复古胶片相机这款软件,以其独特的复古风格和丰富的胶片滤镜效果,让用户仿佛穿越回了那个胶片摄影的黄金时代。它不仅模拟了胶片相机的操作界面,还提…...

通俗易懂的 JS DOM 操作指南:从创建到挂载
目录 🧩 1. 创建元素:document.createElement / createElementNS 📝 2. 创建文本:document.createTextNode ✏️ 3. 修改文本:node.nodeValue 🗑️ 4. 移除元素:el.removeChild() …...

CSS Day07
1.搭建项目目录 2.网页头部SEO三大标签 3.Favicon图标与版心 (1)Favicon图标 (2)版心 4.快捷导航 5.头部-布局 6.头部-logo 7.头部-导航 8.头部-搜索 9头部-购物车 10.底部-布局 11.底部-服务区域 12.底部-帮助中心 13.底部-版权…...
爬虫框架:scrapy使用心得
文章目录 前言一、scrapy是什么?二、使用步骤1.安装和创建2.请求以及参数3.代理池4.请求错误处理5.采集数据入库6.日志及其他配置 总结 前言 有些时候我们需要采集大量数据时,我们需要程序的运行效率高,当然如果有时候不想写请求代码的时候,这些情况我都…...

RV1126-OPENCV 交叉编译
一.下载opencv-3.4.16.zip到自己想装的目录下 二.解压并且打开 opencv 目录 先用 unzip opencv-3.4.16.zip 来解压 opencv 的压缩包,并且进入 opencv 目录(cd opencv-3.4.16) 三. 修改 opencv 的 cmake 脚本的内容 先 cd platforms/linux 然后修改 arm-gnueabi.to…...

【深度学习】 19. 生成模型:Diffusion Models
Diffusion Models Diffusion Models 简介 Diffusion 模型是一类通过逐步添加噪声并再逆向还原的方式进行图像生成的深度生成模型。其基本流程包括: 前向过程(Forward Process):将真实图像逐步加噪,最终变为高斯噪声…...

JMeter 直连数据库
1.直连数据库的使用场景 1.1 参数化,例如登录使用的账户名密码都可以从数据库中取得 1.2 断言,查看实际结果和数据库中的预期结果是否一致 1.3 清理垃圾数据,例如插入一个用户,它的ID不能相同,在测试插入功能后将数据删…...

易路 iBuilder:解构企业 AI 落地困境,重构智能体时代生产力范式
一、从大模型到智能体的产业跃迁 2024 年堪称中国人工智能产业的 "战略拐点" 之年。当 DeepSeek R1 模型以 "技术 价格" 双重普惠模式掀起行业震荡时,各企业纷纷意识到,大模型的真正价值不在于技术炫技,而在于成为企业…...
数据库,Spring Boot,数据源
您是对的,我之前的回答解释了Spring Boot在操作MySQL时不一定需要显式配置指定的数据源类型,因为它有自动配置机制,但没有直接点明在自动配置情况下“数据源是什么”。 在Spring Boot自动配置机制下,这个“数据源”指的是一个连接…...
Linux 第三阶段课程:数据库基础与 SQL 应用
数据库定义 数据库是按一定规则存储数据的仓库,可存储海量数据(百万级至亿级),数据来源包括文本、图像、音视频等多种形式,如出行记录、消费数据等。 数据库分类 关系型数据库:基于二维表格模型࿰…...