概述

  • 在这个warmup实验中,你会完成如下内容
    • 搭建Linux环境
    • learn how to perform some tasks over the Internet by hand, write a small program in C++ that fetches a Web page over the Internet, and implement (in memory) one of the key abstractions of networking: a reliable stream of bytes between a writer and a reader
  • 整个实验预计花费2~6小时
  • 3个注意点
    • 在开始实验前先完整地浏览一遍实验文档
    • Over the course of the class, you’ll be building up your own implementation of a significant portion of the Internet—a router, a network interface, and the TCP protocol (which transforms unreliable datagrams into a reliable byte stream). Most of the labs will build on work you have done previously, i.e., you are building up your own implementation gradually over the course of the quarter, and you’ll continue to use your work in future labs. This makes it hard to “skip” a lab
    • 实验文档是需求文档性质的,而不是可以照葫芦画瓢的保姆式教程

实验规定

  • 独立完成编程作业,不要copy网上或者同学的代码,如果参考了别人的代码,请指明来源
  • 可以和别人讨论,请指明讨论者
  • Piazza: Please feel free to ask questions on Piazza, but please don’t post any source code

准备Linux环境

方法一

方法二

方法三

Networking by hand(使用telnet)

获取网页

  1. 在浏览器中访问:http://cs144.keithw.org/hello,观察结果

image.png

  1. 连接到linux,在终端输入telnet cs144.keithw.org http,等到出现如下界面表示连接成功

image.png

  1. 输入如下指令,注意最后的换行 ```shell GET /hello HTTP/1.1 Host: cs144.keithw.org Connection: close
  1. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/3018011/1613738185022-63258a63-a363-4555-bb19-e6f8067a951e.png#align=left&display=inline&height=303&margin=%5Bobject%20Object%5D&name=image.png&originHeight=303&originWidth=369&size=19725&status=done&style=none&width=369)
  2. 4. Assignment: Now that you know how to fetch a Web page by hand, show us you can! Use the above technique to fetch the URL [http://cs144.keithw.org/lab0/sunetid,](http://cs144.keithw.org/lab0/sunetid,) replacing sunetid with your own primary SUNet ID. You will receive a secret code in the X-Your-Code-Is: header. Save your SUNet ID and the code for inclusion in your writeup
  3. ```shell
  4. telnet cs144.keithw.org http
  5. GET /lab0/666 HTTP/1.1
  6. Host: cs144.keithw.org
  7. Connection: close

image.png

△发送邮件

这个实验步骤用到了stanford域名的邮箱,我就不做了,可以搜索国内的博客尝试使用telnet发送电子邮件

启动一个简单的服务器

这个实验使用netcat在VM上构建了一个简单的服务器,并在另一个终端使用telnet连接

  1. 在一个终端用netcat构建服务器:netcat -v -l -p 9090
  2. 在另一个终端使用telnet连接:telnet localhost 9090,此时在服务器终端可以看到“Connection from localhost 53500 received!”
  3. 在服务器终端输入字符串和回车,客户端可以看到;在客户端输入字符串和回车,服务器也可以看到
  4. 在服务器终端输入Ctrl+C退出,客户端终端也立即退出

    使用OS提供的stream socket编写网络应用

    概述

  • 我们将编写一个简单的程序,用于抓取互联网上的网页
  • 你将用到由操作系统提供的功能:stream socket,创建一个可靠的全双工字节流,在网络上的两台主机之间通信
    • stream socket就像一个普通的file descriptor(类似于磁盘上的一个文件,或者stdin/stdout IO streams)
    • 当分属于网络上的两台主机的两个stream socket连接后,从一台主机的stream socket输入的字节,最终都会按序在另一台主机的stream socket输出
  • 因特网中的网络层IP提供的通信服务是不可靠的,数据可能乱序、丢失、重复、差错;需要由传输层TCP协议,在端系统中实现可靠的数据传输,并进行流量控制和拥塞控制
  • 本实验中,实际上是用到了操作系统预置的TCP服务接口,你将写一个叫做“webget”的程序
      1. 创建1个TCP stream socket
      1. 连接到Web服务器
      1. 抓取网页
  • 在后续实验中,我们将自己实现一个TCP服务

    项目准备

    拷贝并编译项目

  • 实验的基础代码库地址:https://github.com/cs144/sponge,名为Sponge

  • 将代码拷贝到linux中
  • 执行如下命令尝试编译

    1. cd sponge
    2. mkdir build
    3. cmake ..
    4. make -j4
  • writeups/lab0.md是本实验的checkList,需要提交,请认真填写

    使用现代C++

  • 使用C++11后的现代语法风格

  • 好处:绝大多数时候是安全的,而且是快速的、靠近底层的
  • 每个对象有最小的接口,内部有许多安全性检查,不太可能被错误的使用,内部编写了清理机制
  • 避免成对的操作(malloc/free、new/delete),使用RAII
  • 特变的,我们希望你

    • 参考文档:https://en.cppreference.com/
    • 不要使用malloc()、free()
    • 不要使用new、delete
    • 不要使用原始的指针,使用智能指针进行代替(CS144中不需要)
    • 避免使用模板、多线程、锁、虚函数(CSS144中不需要)
    • 避免使用C风格的字符串(char *str)或者相关函数(strlen()、strcpy()),使用std::string代替
    • 避免使用C风格的类型转换(例如,(FILE*) x),使用C++的static_cast如果必要的话(CS144中一般是不需要的)
    • 函数参数尽量加上const
    • 每个变量尽量加上const,除非它会变化
    • 每个方法尽量加上const,除非它需要修改对象
    • 避免全局变量,把每一个变量放在适合它的最小作用域内
    • 在提交代码前,记得运行make format检查编码风格

      使用git

  • 尽可能多的commit,每个commit写清楚干了什么

  • git提交历史将作为评分的依据

阅读Sponge的文档

  • Sponge中提前编写好的类也使用了C++的现代语法风格
  • 文档地址:https://cs144.github.io/doc/lab0/,浏览一遍
  • 尤其注意FileDescriptor、Socket、TCPSocket、Address这几个类(TCPSocket是Sokect的子类,Sokect是FileDescriptor的子类)
  • 浏览一遍libsponge/util文件夹中的如下几个头文件
    • file_descriptor.hh
    • socket.hh
    • address.hh

      编写webget

      可以使用vscode的SSH远程连接,进行远程编辑

步骤:

  1. 打开apps/webget.cc文件
  2. 在get_URL方法中,找到“// Your code here”
  3. 在这里实现一个简单的Web客户端,即抓取Web网页的功能
    1. 使用HTTP请求
    2. 涉及TCPSocket和Address类
  4. 提示:
    1. 注意HTTP每一行以\r\n结尾
    2. 注意设置HTTP的首部字段“Connection: close”,这样服务器端才会关闭这个HTTP请求的输出流,然后客户端才可以从socket中读到“EOF”,表示已经读完了服务器的全部响应
    3. 只调用一次read是不够的,一定要读到EOF才算读完了服务器的全部响应
    4. 代码在10行左右
  5. make指令编译程序
  6. 简单测试代码

    1. ./apps/webget cs144.keithw.org /hello
  7. 运行提前准备好的测试:make check_webget

    1. 在编写前,这个指令的输出如下

image.png
b. 在编写好正确的代码后,这个指令的输出如下
image.png

单机的内存中的可靠字节流

  • 前面的实验中,我们了解了网络通信中的一个可靠的字节流,本小节我们实现一个单机的内存中的可靠字节流(你可能在CS110中已经做过了类似的作业)
  • 要求
    • 字节从“input”一侧写入,从“output”侧按顺序读出
    • 设置有限的容量,进行流量控制,限制任意时刻的内存消耗
      • 初始化设置容量为“capacity”,即任意时刻这个字节流对象用于存储字节数据所消耗的最大内存
      • writer如果写满了,就不能再写入更多的字节,直到reader读出数据,writer才可以继续写入
      • reader如果读空了,就会读到 “EOF”(end of file)
    • 无需实现线程安全
    • 要求能够处理数据量远远大于“capacity”的字节流
  • 下图是writer的接口

image.png

  • 下图是reader的接口

image.png

  • 请打开libsponge/byte_stream.hh和libsponge/byte_stream.cc这两个文件,编写一些实现上述接口的对象
  • 运行make check_lab0进行测试

    展望

    在接下来的四周内,你将实现一个在网络中运行的可靠的字节流,也就是TCP协议的实现

    提交注意事项

  • 只修改webget.cc、libsponge/byte_stream.hh、libsponge/byte_stream.cc这3个文件

  • 在提交前,请按顺序运行
    • make format
    • make
    • make check_lab0
  • 编辑writeups/lab0.md
  • 提交指南:https://cs144.github.io/submit