最简单的 “Lab”
Lab 7
Lab 7 什么代码都不需要写。Just putting it all together !
这个 Lab 将之前 7 个实验里所有实现的内容全部整合在一起,并完成一些测试,与真实网络进行通信。
下面是我们实现的最终网络技术栈的结构图,
测试
对话通信
上图中你可能会注意到底部是 cs144.keithw.org
,因为我们普通家庭用户都是位于 NAT 网络转换背后的,所以作者在 cs144.keithw.org
上搭建了服务,可以让两个 partner 之间通过 cs144.keithw.org
作为中继器(relay)进行消息传输。
❗ 注意,你可能需要在多尝试几次寻找可用的端口号,至少文档中默认的 3000 我试了是不行的。(开始我我还以为作者把服务器关了,心理一凉🥺)
发送一个文件
dd if=/dev/urandom bs=1M count=1 of=/tmp/big.txt
./apps/lab7 server cs144.keithw.org 4090 < /tmp/big.txt
./apps/lab7 client cs144.keithw.org 4091 > /tmp/big-received.txt < /dev/null
sha256sum /tmp/big.txt
sha256sum /tmp/big-received.txt
下面可以看到成功传输了 1MB 的文件
用自己实现的 TCP 协议与计网实验程序通信
为了测试和体现自己 TCP 协议的通用性,我尝试用自己实现的 TCP 协议,ARP 协议,路由匹配算法与学校计网实验的 socket 程序进行远程通信 😍
下面是用 CS144 实现的 TCP 协议写的 client 端的代码,server 端同学校计网实验的单进程简单回声,
#include "address.hh"
#include "tcp_sponge_socket.hh"
#include "util.hh"
#include <cstdlib>
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char *argv[]) {
if (argc != 3) {
printf("Usage: %s <ip_address> <port>\n", argv[0]);
return EXIT_FAILURE;
}
FullStackSocket socket;
socket.connect(Address(argv[1], stoi(argv[2])));
string input;
while (getline(cin, input)) {
input += '\n';
socket.write(input);
cout << "[REPLY] " << socket.read();
}
socket.wait_until_closed();
return 0;
}
经过 C++ 的封装后,比 C 语言简单而优雅了很多😋。
以下是测试成功截图,client 运行在本地,server 运行在远程服务器上
为了更清晰的看到实际传输情况,和 TCP 数据报的具体内容,我决定安装 wireshark。
首先需要给虚拟环境装上 ubuntu-desktop
,
sudo apt update
sudo apt upgrade
sudo apt install ubuntu-desktop
但是发生了比较尴尬的事,Ubuntu 的主分区空间不足,于是我通过 VirtualBox 扩容到 20G,但是在 Ubuntu 中并不会生效,还需要重新调整分区大小。
cs144@vm ~> df -h
Filesystem Size Used Avail Use% Mounted on
tmpfs 794M 9.1M 785M 2% /run
/dev/sda2 9.8G 9.8G 0 100% /
tmpfs 3.9G 0 3.9G 0% /dev/shm
tmpfs 5.0M 4.0K 5.0M 1% /run/lock
tmpfs 794M 20K 794M 1% /run/user/1000
cs144@vm:~$ sudo fdisk -l
...
Disk /dev/sda: 20 GiB, 21474836480 bytes, 41943040 sectors
Disk model: VBOX HARDDISK
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 864409E8-FEDC-4E44-B57B-302B291A9A18
...
从中可以看出根分区是 /dev/sda2
,下面是 Ubuntu 命令行扩容的具体步骤:
- 打开终端窗口。
-
运行以下命令来扩展分区
/dev/sda2
:sudo parted /dev/sda resizepart 2
这会启动交互式模式,让你选择新的分区大小。你可以输入
Yes
来使用所有可用空间。 -
接下来,运行以下命令来更新文件系统以反映分区的扩展:
sudo resize2fs /dev/sda2
- 完成后,你可以运行以下命令来查看新的磁盘空间:
df -h
现在应该将能够看到根分区已经扩展到了新的空间大小。
扩容成功😀,
重启进入系统,
这时候为了更高的显示分辨率和更好的 GUI 体验,你还需要安装虚拟机拓展包。最后安装成功后你就可以像下面这样变大啦,
安装并启动 wireshark,
sudo apt install wireshark
sudo wireshark
选择虚拟网卡 tap10,这是要使用自己实现的 TCP、ARP 协议和路由匹配算法必须依赖的东西,它可以绕过 Linux kernel 的协议栈。
之后就可以愉快抓包观察,自己实现的 TCP 协议与对方真实网络世界通信的情况啦🤗
2023.8.19 终于写完了 CS144 的所有 8 个 Lab,并成功用自己实现的 TCP 协议,ARP 协议,路由匹配算法与学校计网实验的 socket 程序进行远程通信,完结撒花!🎉🥳
不过目前对 Linux 的虚拟设备 TUN/TAP 原理也还不太了解,不得不赞叹 Lab 作者网络领域的巨擘 Keith Winstein 教授的巧妙设计,另外 ByteStream
也还可以再优化从而提高 CPU 吞吐量,等以后有缘再会吧。