CS144 - lab 0

date
Nov 25, 2022
slug
cs144-lab0
status
Published
tags
计算机网络
summary
简单的热身运动
type
Post
 

简介

我跟的是 Fall 2021 的课程
本次 lab 对应 week 1,阅读资料都是一些基本的网络概念,这里就不介绍了,感兴趣可以自己翻阅一下
notion image

环境

我的是 m1pro 的 mbp,用 pd 开了一个虚拟机,然后用 vscode ssh 链接进行 coding
首先是安装环境
下面就可以愉快的学习了

2 Networking by hand

finish two tasks:
  • retrieving a web page
  • sending an email message
这些任务依赖于一个叫做 reliable bidirectional byte stream 的网络抽象

2.1 Fetch a Web page

两个操作:
notion image
notion image
等待链接建立后,输入以下命令并观察结果
我们请求命令的含义分别是:
  • GET /hello HTTP/1.1,告诉 server 我们想要访问的 URL 路径,这里是 /hello
也就是我们的请求行
  • Host: cs144.keithw.org,告诉 server 我们想要访问的 host,指的是 http:///hello 中间的数据
完整的路径是 http://cs144.keithw.org/hello
  • Connection: close,告诉 server,一旦返回结果就可以立即关闭
像这种 K:V 型的数据就是请求头啦
 
输入后得到结果,cool
notion image
这里有一个任务
notion image
就是按照上面的流程走一遍,我不知道SUNet ID在哪里获取,我自己随便打了一个
notion image
注意看header里面的字段,确实有一个997480的值返回

2.2 Send yourself an email

用 smtp(Simple Mail Transfer Protocol)协议给自己发一封邮件
这个环节需要用 standford 的网络环境才能完成,跳过了

2.3 Listening and connecting

下面用 netcattelnet 来做一个双向通信
  1. netcat -v -l -p 9090 来监听 9090 端口
  1. 在另一个 terminal,用 telnet localhost 9090 来链接 9090 端口
然后你会发现它们可以双向通信了
notion image

3 Writing a network program using an OS stream socket

3.1 Let’s get started —— fetching and building the starter code

运行 git clone https://github.com/cs144/sponge 下载lab的源代码
notion image
文档里面的准备工作写得很详细,我自己没有遇到问题,可以直接进入3.2了

3.2 Modern C++: mostly safe but still fast and low-level

又到了喜闻乐见的 C++ 环节,课程用的是 C++ 11,课程提出了一些要求:
  • 尽量避免使用成对操作,比如说 malloc/free, new/delete,因为后面的操作可能会因为异常或者提前退出而不能正确执行
下面还有一些规范,这里就不翻译了:
notion image

3.3 Reading the Sponge documentation

ok,然后这边给了几个文档读
notion image
这里给了官方文档说明,主要是四个类要我们阅读
  • FileDescriptor ⇒ Socket ⇒ TCPSocket
  • Address 是 Socket 需要绑定的地址类
  • 然后看这个 libsponge/util 里面有源码

3.4 Writing webget

接下来就可以愉快的写代码了,第一个任务呢只给了我们一个函数,要求我们补全它的功能。
注释写得很详细,同时这里文档也给出了一些提示
notion image
怎么做的我们先看注释
首先注释要求我们去链接 http service,那么自然我们需要绑定Address,看一下它里面的构造函数。
notion image
这个看起来符合我们的要求,这里也给了提示,http是80端口,另外
/etc/services 文件包含网络服务和它们映射端口的列表。详细介绍可以看: Services (網路服務設定檔) - 維基百科,自由的百科全書 (wikipedia.org) 技术|理解 Linux 中的 /etc/services 文件
notion image
我们看看里面的说明,果然http是绑定到了80端口,而https绑定了443接口,根据协议还分为基于tcp的https和基于udp的https(也就是HTTP/3)
那么我们简单地使用Address addr(host, "http"); 获取一个地址,回头继续看文档,还提示了我们用TCPSocket,经过一番摸索之后终于理解了这个get_URL的含义:
  • 用TCPSocket链接指定的host,然后写入相应的请求,并打印返回值
通过测试了:
notion image
内容其实就是开始的时候,让我们手写HTTP请求获取结果一样,这里写了一个GET的请求,还有请求头说明host和connection的方式
比如我们用写好的函数,测试cs144.keithw.org /hello ,也能够得到正确的结果
notion image

4 An in-memory reliable byte stream

接下来要我们实现一个An in-memory reliable byte stream,特点:
  • 长度限制writer写入的数量,但是并不限制整个传输的信号量。
  • 当writer写入到limit的时候就不能再写了,只有reader取出数据才能继续写,就像生产者和消费者模型一样。
writer的接口:
notion image
reader的接口:
notion image
实现的地方在libsponge/byte stream.hh and libsponge/byte_stream.cc
想了一下,这个需求双端队列应该很好写,write往队首写,reader向队尾取,队列的size提前给定了
注意到文档没有给出边界情况怎么处理:
  • reader想要读取的字符长度超过了队列的大小,应该怎么处理,直接报错还是直接读取尽可能大的字符?
  • 我写入的字符串大于队列大小,应该丢弃多余的字符,还是保存下来再写入?
文档开头也说了,本次课程的实验部分的需求不会写得很详细,需要我们自己摸索然后设计一个解决方案,这是因为以后工作的时候遇到很多需求都是很模糊的,这么做是为了提前训练学生的设计能力。
想了一下,这是一个经典的生产者消费者问题,用双端队列能够很好的满足我们的需求
  • writer在队头写,reader取队尾
  • 限制最大存储容量cap,通过队列元素个数和cap计算得到剩余可以写入的元素个数
除此之外有几个要注意的地方
  • eof 表示 reader 是否读取结束,状态由队列当前元素个数和 writer 是否写入结束共同决定
  • pop_output 同样也要计算读取个数
搞清楚之后实现还是很简短的,跑了一下,都通过了
notion image
debug技巧
测试文件位于tests文件夹中,点进去能直接看到测试用例和预期结果,每个测试用例还会提示你完成了多少命令,在哪一个命令出错了,通过这种方式可能节省很多debug的时间。
notion image

总结

lab0 整体上是一个热身运动
  • 通过 linux 自带的指令体验了一下 http 请求
  • 要求我们自己实现一个简单的 get_URL 函数去发送请求并获取结果,涉及到 Socket 和网络通信的基本知识
  • 最后的 An in-memory reliable byte stream 要求我们实现了一个生产者消费者模型,还是比较有意思的
 
 

© hhmy 2019 - 2024