当前位置: 首页 > news >正文

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

相关文章:

  • LINUX528 重定向
  • 【Linux】分页式存储管理:深刻理解页表映射
  • 具身智能专题(2)-主从臂零位校准及摄像头数据获取与检验
  • ESP8285乐鑫SOCwifi芯片32bit MCU和2.4 GHz Wi-Fi
  • 第11章:工程组织与系列总结
  • 前端EXCEL插件智表ZCELL数据源功能详解
  • 最长公共子序列(LCS)问题——动态规划法
  • 动静态库的制作
  • MYSQL备份恢复知识:第六章:恢复原理
  • 排查Oracle文件打开数过多
  • 万字详解RTR RTSP SDP RTCP
  • 内网穿透系列五:自建SSH隧道实现内网穿透与端口转发,Docker快速部署
  • es6 函数解构
  • 不打架的协议互通,modbus转profibus网关的总线的高效互通方案
  • 通用大数据可视化展示平台模板 – 免费HTML源码
  • 解锁 AI 开发新境界:OPE Pod 开放平台深度解析
  • 云服务器系统盘满了,但是其他正常,是否可能是被攻击了
  • BSS / OSS 是什么
  • 软件测试环境搭建及测试过程
  • 软件测试的潜力与挑战:从“质量守门员”到“工程效能催化剂”的进化
  • 三网合一网站建设公司/竞价推广账户竞价托管收费
  • 网站流量大小对网站有什么影响/武汉大学人民医院地址
  • 动态网站开发的语言/台州百度快照优化公司
  • 可以自己做网站/惠州网站seo排名优化
  • 网站ftp密码/最好的bt磁力搜索引擎
  • 网站运营管理主要内容/网络运营怎么学