CS144 - LAB0

news2025/6/3 19:43:32

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";
  // 通过域名解析获取 ip
  struct 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/build
    Start 1: compile with bug-checkers
1/2 Test #1: compile with bug-checkers ........   Passed    0.20 sec
    Start 2: t_webget
2/2 Test #2: t_webget .........................   Passed    1.10 sec

100% tests passed, 0 tests failed out of 2

Total 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 interfaces
  Reader& 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/build
      Start  1: compile with bug-checkers
 1/11 Test  #1: compile with bug-checkers ........   Passed    0.85 sec
      Start  2: t_webget
 2/11 Test  #2: t_webget .........................   Passed    1.27 sec
      Start  3: byte_stream_basics
 3/11 Test  #3: byte_stream_basics ...............   Passed    0.02 sec
      Start  4: byte_stream_capacity
 4/11 Test  #4: byte_stream_capacity .............   Passed    0.01 sec
      Start  5: byte_stream_one_write
 5/11 Test  #5: byte_stream_one_write ............   Passed    0.01 sec
      Start  6: byte_stream_two_writes
 6/11 Test  #6: byte_stream_two_writes ...........   Passed    0.02 sec
      Start  7: byte_stream_many_writes
 7/11 Test  #7: byte_stream_many_writes ..........   Passed    0.10 sec
      Start  8: byte_stream_stress_test
 8/11 Test  #8: byte_stream_stress_test ..........   Passed    0.03 sec
      Start 37: no_skip
 9/11 Test #37: no_skip ..........................   Passed    0.01 sec
      Start 38: compile with optimization
10/11 Test #38: compile with optimization ........   Passed    3.15 sec
      Start 39: byte_stream_speed_test
        ByteStream throughput (pop length 4096): 11.88 Gbit/s
        ByteStream throughput (pop length 128):   2.13 Gbit/s
        ByteStream throughput (pop length 32):    0.56 Gbit/s
11/11 Test #39: byte_stream_speed_test ...........   Passed    0.36 sec

100% tests passed, 0 tests failed out of 11

Total Test time (real) =   5.84 sec
Built target check0

clear

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

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

相关文章

论文浅尝 | 将复杂知识图谱问答对齐为约束代码生成(COLING2025)

笔记整理&#xff1a;康家溱&#xff0c;东南大学在读硕士&#xff0c;研究方向为代码大语言模型 论文链接&#xff1a;https://aclanthology.org/2025.coling-main.267.pdf 发表会议&#xff1a;COLING 2025 1. 动机 近年来&#xff0c;随着大语言模型&#xff08;LLM&#xf…

Golang|分布式搜索引擎中所使用到的设计模式

迭代器模式 定义&#xff1a;在遍历接口时&#xff0c;提供统一的方法函数供调用&#xff0c;保持一致性。核心思想&#xff1a;与大众习惯保持一致&#xff0c;方便第三方实现容器类时保持一致。常见方法&#xff1a;如next()方法&#xff0c;适用于所有集合类&#xff0c;简化…

Ubuntu22.04通过命令行安装qt5

环境&#xff1a; VMware17Pro ubuntu-22.04.5-desktop-amd64.iso 步骤&#xff1a; 安装好虚拟机进入shell&#xff0c;或通过ssh登录&#xff0c;确保虚拟机能上外网&#xff0c;执行命令&#xff1a; sudo apt update sudo apt install build-essential sudo snap in…

STM32:ESP8266 + MQTT 云端与报文全解析

知识点1【MQTT的概述】 1、概述 MQTT是一种基于发布/订阅模式的轻量级应用层协议&#xff0c;运行在TCP/IP协议之上&#xff0c;专用物联网&#xff08;IoT&#xff09;和机器对机器&#xff08;M2M&#xff09;设计&#xff0c;其核心目标是低带宽&#xff0c;高延迟或不稳定…

HTML5 Canvas 星空战机游戏开发全解析

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

箱式不确定集

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

内存管理 : 04段页结合的实际内存管理

一、课程核心主题引入 这一讲&#xff0c;我要给大家讲的是真正的内存管理&#xff0c;也就是段和页结合在一起的内存管理方式。之前提到过&#xff0c;我们先学习了分段管理内存的工作原理&#xff0c;知道操作系统采用分段的方式&#xff0c;让用户程序能以分段的结构进行编…

vue3: baidusubway using typescript

项目结构&#xff1a; <!--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原生分布式分片…

常见相机的ISP算法

常见的ISP算法 3A算法 去雾算法 图像增强算法 图像宽动态算法 图像的电子缩放算法&#xff0c;无极电子缩放 图像降噪算法 相机常见问题 1.相机启动速度问题&#xff0c;启动速度较慢 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复古胶片相机:穿越时光,定格经典

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

通俗易懂的 JS DOM 操作指南:从创建到挂载

目录 &#x1f9e9; 1. 创建元素&#xff1a;document.createElement / createElementNS &#x1f4dd; 2. 创建文本&#xff1a;document.createTextNode ✏️ 3. 修改文本&#xff1a;node.nodeValue &#x1f5d1;️ 4. 移除元素&#xff1a;el.removeChild() &#x1…

CSS Day07

1.搭建项目目录 2.网页头部SEO三大标签 3.Favicon图标与版心 &#xff08;1&#xff09;Favicon图标 &#xff08;2&#xff09;版心 4.快捷导航 5.头部-布局 6.头部-logo 7.头部-导航 8.头部-搜索 9头部-购物车 10.底部-布局 11.底部-服务区域 12.底部-帮助中心 13.底部-版权…

RV1126-OPENCV 交叉编译

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

【深度学习】 19. 生成模型:Diffusion Models

Diffusion Models Diffusion Models 简介 Diffusion 模型是一类通过逐步添加噪声并再逆向还原的方式进行图像生成的深度生成模型。其基本流程包括&#xff1a; 前向过程&#xff08;Forward Process&#xff09;&#xff1a;将真实图像逐步加噪&#xff0c;最终变为高斯噪声…

JMeter 直连数据库

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

易路 iBuilder:解构企业 AI 落地困境,重构智能体时代生产力范式

一、从大模型到智能体的产业跃迁 2024 年堪称中国人工智能产业的 "战略拐点" 之年。当 DeepSeek R1 模型以 "技术 价格" 双重普惠模式掀起行业震荡时&#xff0c;各企业纷纷意识到&#xff0c;大模型的真正价值不在于技术炫技&#xff0c;而在于成为企业…

计算机网络之路由表更新

1.解题思路 对新接收到的路由表进行更新&#xff0c;全部"距离"1&#xff0c;且"下一跳路由器"都写成发送方路由器的名称。 开始对比新表和原来的路由表 1.看目的网络 如果是新的目的网络&#xff0c;则直接把对应的各项信息填入表中&#xff1b;如果是相同…

万兴PDF手机版

万兴PDF手机版(万兴PDF编辑器)是一款国产PDF编辑工具.万兴PDF安卓版提供PDF文档编辑,AI撰写摘要,文档签名,设置密码保护等功能,万兴PDF专家APP以简约风格及文档编辑功能为核心,支持多设备终端同步保存.全免 万兴 PDF 编辑器是一款功能强大的 PDF 编辑软件&#xff0c;它支持多种…