Qurak

Make Code Talk

0%

CS144Lab0

目录

  • CS144 实验介绍
  • Lab0: networking warmup
    • 配置实验环境
    • 利用一些网络工具
    • 完成 webget

CS144 实验介绍

CS144 实验是斯坦福大学计算机网络课程的实验,也是我选修计科计算机网络的实践内容。核心是手写一个简单的 TCP 传输,并在这个过程中明白 TCP 具体是如何运作的。但受限于上课时时间紧张,并没有好好写,因此打算利用一下放假的时间好好再研究一下。

详情可以点击这个链接 ➡️ CS144 实验网址

Lab0: networking warmup

1. 配置实验环境

具体的配置可以查看文档,以下是我的环境

  • 虚拟机:VMware 16
  • 系统:Ubuntu 20.04.3 LTS
  • GCC:9.3.0 x86_64-linux-gnu
  • CMake: 3.21.2

2. 利用一些网络工具

2.1 使用 telnet 抓取一个网页

⚠️ 首先请确保可以正常访问 http://cs144.keithw.org/hello

1
2
3
4
5
6
7
8
9
10
11
12
13
# 使用 telnet 的工具来抓取 cs144.keithw.org/hello 的页面内容
telnet cs144.keithw.org http
# 输出:
# Tring 104.196.238.229...
# Connection to cs144.keithw.org.
# Escape character is '^]'
# 以下输入 http 报文内容
GET /hello HTTP/1.1
Host: cs144.keithw.org
Connection: close

#
# 等待一会就会看到和正常访问一样的内容

在实践的时候出了一些问题,但最后都解决了:

  • 刚输入完 Connection: close 发现服务器直接关闭了连接,并返回 Connection closed by foreign host. 这个时候可以尝试先输入前两行内容,等待返回数据后再关闭连接。
  • 输入好的报文后回车没反应。此时可以尝试 tab+回车 来发送报文

然后就使用相同的方法来访问 http://cs144.keithw.org/lab0/sunetid (其中 sunetid 可以随意填写)

2.2 发送 email

这个比较简单但是挺琐碎的,跳过。

2.3 本地创建监听和连接

使用 netcat 创建本地服务器并开启监听, telnet 连接本地服务器。

1
2
3
4
5
6
7
8
9
# netcat 创建本地 9090 端口并监听
netcat -v -l -p 9090
# 若以上命令报错
# netcat: getnameinfo: Temporary failure in name resolution
# 则多加一个 -n
netcat -v -l -n -p 9090

# 在另一个终端使用 telnet 连接
telnet localhost 9090

成功连接后,在 telnet 中发送数据,可以在 netcat 中看到。关闭 netcat 则双方都关闭

3. 完成 webget

从现在开始才是 CS144 的真正开始,我们需要自顶向下慢慢完善我们的 TCP 连接。在 lab0 中,我们需要基于 cs144 所提供的 sponge 框架中完成类似 telnet 发送报文并输出返回报文的功能。

代码下载完后首先使用 cmake 得到工程,在 build 文件中可以使用 make help 来获取有关 sponge 的资料。

在本次试验中,我们需要完成 webget.cc 中的 get_URL() 函数。其中需要具有 创建套接字连接服务器发送报文获取完整输出

通过查阅帮助文档,可以知道我们需要使用到 TCPSocket ,具体的调用可以参考文档和目标功能。总体还是比较简单的:1、建立套接字连接;2、利用套接字连接服务器;3、创建报文并发送(注意每一行需要 \r\n,以及最后一行要多一个空行表示发送结束);4、读取返回的报文信息,读取至 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.
TCPSocket tcp_socket;
tcp_socket.connect(Address(host, "http"));
std::string request("GET "+path+" HTTP/1.1\r\n"
"Host: "+host+"\r\n"
"Connection: close\r\n\r\n");
tcp_socket.write(request);
// 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).
while(!tcp_socket.eof())
{
std::cout << tcp_socket.read(1);
}
tcp_socket.shutdown(SHUT_WR);
// only shutdown write, the socket will continue reading data until get eof

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

编译后可以 ./build/apps/webget cs144.keithw.org /heelo 来测试一下是否正确。

大致没问题,可以使用 make check_webget 来测试代码:

image-20220113000250485