Lab0 Networking Warmup

Introduction

Set up

这里直接使用官方提供的虚拟机镜像:
https://stanford.edu/class/cs144/vm_howto/vm-howto-image.html

Networking by hand

使用 Telnet 访问 web

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
cs144@cs144vm:~$ telnet cs144.keithw.org http
Trying 104.196.238.229...
Connected to cs144.keithw.org.
Escape character is '^]'.
GET /hello HTTP/1.1
Host: cs144.keithw.org
Connection: close

HTTP/1.1 200 OK
Date: Mon, 08 Mar 2021 11:59:22 GMT
Server: Apache
Last-Modified: Thu, 13 Dec 2018 15:45:29 GMT
ETag: "e-57ce93446cb64"
Accept-Ranges: bytes
Content-Length: 14
Connection: close
Content-Type: text/plain

Hello, CS144!
Connection closed by foreign host.

由于没有 SUNet ID,所以跳过部分实验。104.196.238.229

Send yourself an email

同样还是跳过

Listening and connecting

使用netcat监听9000,并使用telnet访问。

1
2
3
netcat -v -l -p 9000
# 在另一个终端中
telnet localhost 9090

Writing a network program using an OS stream socket

Let’s get started

代码 repo: https://github.com/cs144/sponge

可以考虑创建一个仓库,然后通过import的方式备份到自己的 GItHub 中,然后再 clone。

编译代码:

1
2
3
4
mkdir build
cd build
cmake ..
make -j2

Modern C++

代码使用 Modern C++(>= C++11),Reference – CppCoreGuidelines

Basic idea:every object is designed to have the smallest possible public interface, has a lot of internal safety checks and is hard to use improperly, and knows how to clean up after itself.

  • Never use malloc() or free()
  • Never use new or delete
  • Essentially never use raw pointers,and user ‘smart’ pointers
    • unique_ptrshared_ptr
  • Avoid templates, threads, locks and virtual functions.
  • Avoid C-style strings
  • Never use C-style casts, and use static_cast
  • Pefer passing function by const reference
  • Make every variable const unless it need to be mutated.
  • Make every method const unless it need to mutate the object.
  • Avoid global variables.
  • make format

Reading the Sponge documentation

https://cs144.github.io/doc/lab0

  • 从文档来看,FileDescriptor 好像只是把 Linux 下的文件描述符和一些文件操作封装成一个类了。
  • SocketFileDescriptor 的子类,加上了一些和 Socket 相关的API(抽象类)
  • TCPScoektSocket的子类,添加了listenacept等成员方法
  • Adress 是用来申明地址的,可以指定 IP 和端口

Writing webget

这个程序相当于是在代码中实现跑一边用telnect访问cs144.keithw.org的过程,所以建议复习一下lab0-networking-warmup#使用 Telnet 访问 web

在文档里面也给了一些提示:

  • 在网络中使用\r\n而不是\n作为换行符
  • 记得加上Connection: close
  • 不要只使用一次read(),而是需要用eof()来判断是否结束了

实现起来并不复杂,这里直接贴代码,唯一需要注意的就是最后有两个换行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
void get_URL(const string &host, const string &path) {
// Your code here.

// You will need to connect to the "http" service on
// the computer whose name is in the "host" string,
// then request the URL path given in the "path" string.

// Then you'll need to print out everything the server sends back,
// (not just one call to read() -- everything) until you reach
// the "eof" (end of file).
const string payload = "GET " + path + " HTTP/1.1\r\n" + \
"Host: " + host + "\r\n" + \
"Connection: close\r\n\r\n";
Address address(host, "http");
TCPSocket socket;
socket.connect(address);
socket.write(payload);
while (!socket.eof()) {
cout << socket.read();
}
socket.close();

// cerr << "Function called: get_URL(" << host << ", " << path << ").\n";
// cerr << "Warning: get_URL() has not been implemented yet.\n";
}

由于网络的问题,可能会导致在获取IP地址时花费大量时间,所以简易在/etc/hosts文件中配置好IP。例如:

1
sduo echo "104.196.238.229 cs144.keithw.org" >> /etc/hosts

测试:

1
2
3
4
5
6
7
8
9
10
11
cs144@cs144vm:~/sponge/build$ make check_webget
[100%] Testing webget...
Test project /home/cs144/sponge/build
Start 28: t_webget
1/1 Test #28: t_webget ......................... Passed 3.31 sec

100% tests passed, 0 tests failed out of 1

Total Test time (real) = 3.33 sec
[100%] Built target check_webget
cs144@cs144vm:~/sponge/build$

An in-memory reliable byte stream

这一部分是让我们实现一个内存中的字节流,主要有一下几点要求:

  • 通过一个capacity初始化,内存中 Buffer 的大小,当 Buffer 满了之后,限制写,直到有内容被读走了
  • 不需要考虑并发问题
  • the byte stream is finite, but it can be almost arbitrarily long4 before the writer ends the input and finishes the stream.

One More Thing

-