本文为斯坦福大学计算机网络课程 CS144 编程任务 Lab Assignment 0 的学习小结
官网 https://cs144.github.io/
Lab 0 文档 https://cs144.github.io/assignments/lab0.pdf
个人实验备份代码 https://github.com/deepzheng/sponge
环境的安装与配置
官方文档提供了三种支持运行该 Lab 的选择
我还是比较推荐使用课程组提供的 VirtualBox 的镜像的
本来我嫌麻烦,用自己的 Vmware + UBuntu20.04 自己来配置环境,结果在做到第三步运行测试代码 make check_webget
的时候发现报出了离奇的错误。把代码还原到改动之前依然报错,翻遍全网也没有找到解决办法。
最后只能灰溜溜地下载了 VirtualBox 和课程组的 LUBuntu 镜像。之前从没用过lUBuntu 的我看到类 Windows 的界面还是有点别扭2333 好在基本操作大差不差
Networking by hand
这部分内容比较简单,跟着文档一步步做就好了
Fetch a Web page
使用 telnet 发送 http 请求,命令结束后需要两次回车结束请求
Send youself an email
官方文档提供的是斯坦福校内的邮箱服务器,想要完成这个部分就需要使用国内的邮箱服务器了,并且操作上会稍微麻烦一点
我选用的是 QQ 的邮箱服务器,在登陆的时候需要提供账号和校验码的 Base64编码
Listening and connecting
开两个终端分别模拟客户端和服务器端操作。服务器端开启监听模式,等待客户端建立连接之后,就可以收到另一个终端发来的消息了
Writing a network program using an OS stream socket
这一个部分是本 Lab 的核心,需要使用 OS 流套接字编写实现一个get_URL函数以及完成一个字节流控制读写类
Writing webget
模拟上面 telnet 的操作,使用套接字编写 get_URL 函数实现 webget 。
web_get.cc
tips:
- TCP 在建立连接时会由系统隐形 bind 端口,不需要像 UDP 一样手动操作
- 相比于
close()
,shutdown()
提供了一个更为优雅的操作方式。调用close()
函数意味着完全断开连接,即不能发送数据也不能接收数据。而shutdown()
提供了三个变量取值
- SHUT_RD 断开输入流
- SHUT_WR 断开输出流
- SHUT_RDWR 同时断开 I/O 流
- 默认情况下,调用
close()
后无论输入缓冲区中是否有数据都将立即关闭套接字,后续需要发送数据需要再次建立套接字连接。而shutdown()
只用于关闭连接而非套接字,并且shutdown()
会等待输入缓冲区中的数据传输完成后再关闭连接
An in-memory reliable byte stream
该部分需要实现一个简单的可靠字节流类,支持写入、读出、容量控制、流量计算
对于字节流缓冲区的数据结构,本来我是想使用string
来进行双向读写,但是按照现代C++d的要求,应该尽可能避免使用指针,而 string 下标的索引本质上还是指针,所以我最后使用了 deque
双向队列。双向队列支持头尾读写,刚好对应字节流从尾部写入从头部读取的特性,并且拥有迭代器,完美支持了该字节流类中的 peek 操作
byte_stream.hh
byte_stream.cc
任务结束,收工大吉
v1.5.2