CS144 2024 winter 作业笔记

news/2024/11/17 18:36:15/文章来源:https://www.cnblogs.com/ticlab/p/18303909

CS144 2024 winter 作业笔记
cs144 homework notes

Created: 2024-05-14T10:24+08:00
Published: 2024-07-15T20:16+08:00

Categories: ComputerNetwork

目录
  • checkpoint0
    • 配环境
    • weget
    • reliable byte stream
    • 疑问
  • checkpoint1
  • checkpoint2
    • bugs:
  • checkpoint3
    • model of input_
    • Sender
    • timer
    • Sender 和 Receiver 交互的流程
  • checkpoint4
  • checkpoint5
  • checkpoint6
  • checkpoint 7

课程网站: CS 144: Introduction to Computer Networking
我的代码: rfhits/cs144-2024-winter

checkpoint0

配环境

sudo apt update && sudo apt install git cmake gdb build-essential clang clang-tidy clang-format gcc-doc pkg-config glibc-doc tcpdump tshark

配环境遇到好几个问题:

  1. cmake 版本不够,使用 pip install 升级:https://stackoverflow.com/a/52265521/14380036
  2. 在 Windows 内 git clone,在 wsl 内 cmake,导致报错
    no such file or directory
    CMake Error: Generator: execution of make failed. Make command was: /mnt/c/minnow/scripts/make-parallel.sh -f Makefile
    
    解决:git clone 也要在 wsl 内完成
  3. 使用 g++11 编译报错:
    error: invalid return type ‘std::string’ {aka ‘std::__cxx11::basic_string<char>’} of ‘constexpr’ function ‘static constexpr std::string ExpectationViolation::boolstr(bool)’
    16 |   static constexpr std::string boolstr( bool b ) { return b ? "true" : "false"; }
    
    使用 g++12 解决并设置环境变量 CXX 解决,参考 networking - How can I replace gcc with g++-11 for C++20 when running cmake - Stack Overflow
  4. 安装并使用 g++12
    在 linux 中,多个版本的 g++ 是共存的,编译命令中的 g++ 是通过符号链接(symbolic link)到对应的版本,可以通过
    which g++ 看到 g++ 被符号链接到了谁,这个符号链接链接了很多次
    user@unix:~$ which g++
    /usr/bin/g++
    user@unix:~$ file /usr/bin/g++
    /usr/bin/g++: symbolic link to g++-11
    user@unix:~$ which g++-11
    /usr/bin/g++-11
    user@unix:~$ file /usr/bin/g++-11
    /usr/bin/g++-11: symbolic link to x86_64-linux-gnu-g++-11
    user@unix:~$ which x86_64-linux-gnu-g++-11
    /usr/bin/x86_64-linux-gnu-g++-11
    user@unix:~$ file /usr/bin/x86_64-linux-gnu-g++-11
    /usr/bin/x86_64-linux-gnu-g++-11: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=f97745c2db747184cd62fd36ecb924046f3d725f, for GNU/Linux 3.2.0, stripped
    
    pdf 提到了最后是使用 g++ v13.2 测试的,所以最好不要用 clang 编译

weget

把这些 write 到 socket 里面就好了

GET /hello HTTP/1.1
HOST: cs144.keithw.org
Connection: close

最后应该要 shutdown,这部分可以参考 Lecture 02 的 TCP state。

reliable byte stream

用 string 配合 begin end 和 replace 实现的,减少 erase 和 append,可以实现 10+ Gbit/s

本来想是写成 ring-buffer,结果发现 peek() 要返回 string_view,可见还是要通读需求再开始设计。

疑问

cmake --build build --target tidy 虽然是 optional,但是执行的时候报错 -Wno-unqualified-std-cast-call,也不知道怎么解决。

checkpoint1

  1. 针对 last 需要 bool 保护特判,不能直接初始化成 0,在我们不知道 last index 是什么的时候,记录一个变量 know_last为 false

实在是做不到 10Gbits

checkpoint2

bugs:

  1. SYN 携带的 data 也要写入 reassembler。

    因为理论上,SYN 不应该携带 payload,因为需要得到对方的 ack 后才可以发送数据

  2. FIN 会携带数据

  3. receiver 需要记录状态,比如是否开始(SYN),是否结束(FIN),sender() 需要使用状态和 reassember.bytes_pending 决定 ackno。
    如果收到了 FIN,并且没有 pending bytes,ackno 要考虑 FIN 占据了一个 seqno,如果有 pending bytes,不需要考虑 FIN。

checkpoint3

model of input_

一开始我就犯了一个错误并且写了很久导致时间的浪费。

这个错误就是,Sender 的成员 ByteStream 可能是没有关闭的,在 Sender 的视角里,要发送的 Data 长这样:

  1. 这段 data 被 SYN 和 FIN 包裹,因为 SYN 和 FIN 占据 sequence space
  2. FIN 可能还没有出现,SYN 可能还没有发送

Sender.push() 从 bytes in stream 中取出 window size 允许大小的数据,然后发送。读取的方法必须调用 pop(),不然 input_的写端可能没法往里面再写数据了,这里课程组提供了 read() 方法:void read( Reader& reader, uint64_t len, std::string& out )

关于 input_ 只会使用到 3 个接口:

reader.bytes_buffered(): how many bytes not send
reader.is_finished()
void read( Reader& reader, uint64_t len, std::string& out )

将要发送的数据视为 FIN + payload + FIN,这是本科的计算机网络教学没有提及的。

Sender

sender 维护了 segment in flight,每次 push 都只是发送还没发送的 segment,不需要重新发送 segment in flight。因为 segment in flight 可以被 timer 超时重传。

- abs_last_ackno    : uint64 # promise aligned with outstanding segments
- abs_exp_ackno     : uint64 
- wnd_size          : uint64- ost_segs	        : set<uint64, msg>
- retx_cnt          : int # retransmit count
- is_last_retx      : bool
- cur_rto           :

Sender.push()

每次 receive 时候,就是 Receiver 告知 Sender 自己可以接受的数据边界,Sender 根据它来调整自己的窗口大小。

注意,Sender 并非调整自己的窗口 message 中声明的窗口大小,message 只是告知 Sender:Receiver 现在可以处理的数据边界为 msg.ackno + msg.window_size,请把在此边界内的数据全部发送过来。这也是本科学习计算机网络的一个盲区。

Sender 根据 last_ackno 调整窗口大小,如果边界内的数据已经发送了,就不需要再发送,如果还可以发送新的,就要接着从 ByteStream 中取出数据发送。

调整窗口的公式为:last_ackno + sender_window_size = rcv_ackno + rcv_window_size

timer

- bool is_running
- bool is_expired
- uint64 cur_time # remain time
- uint64 exp_time # expire time

timer 的作用:定期检查是否有 segment in flight,如果是,expire 的时候重新发送。

所以发送有 sequence space 的 segment 时候,如果 timer 不在运行,就要启动 timer。

tick: 检查 timer 是否超时,如果是,触发检查。检查发现有 segment in flight,重传并重启 timer;如果没有 segment in flight,清除 timer。

receive:如果收到了新的segment,原来的 timer 就要作废。再检查是否有 segment in flight,如果有就 timer 重启,否则清除 timer。

Sender 和 Receiver 交互的流程

# first time, push a SYN
Sender.push() -- (SYN) --> Receiver# receive data
Sender.receive() <-- (ACK, window_size, ackno) -- Receiver# fill data into window and send to receiver
Sender.push() -- (data) --> Receiver# periodically tick, check timer, for retransmit
Sender.tick() -- (data) --> Receiver

checkpoint4

因为 wsl 没法做,试了半天 CentOS,放弃。最后用 VMware 装虚拟机做了,而且 VMware v17 也是对个人免费的。

发现自己收到的 echo reply seqno 不是连续的,很有规律地 +3。如果把 echo request 的速度改为一秒一次,sequence number 就是连续的,说明 0.2s 发一次,会太快导致丢包。

How independent or correlated is the event of “packet loss” over time? In other words:
• Given that echo request #N received a reply, what is the probability that echo request #(N+1) was also successfully replied-to?
• Given that echo request #N did not receive a reply, what is the probability that echo request #(N+1) was successfully replied-to?
• How do these figures (the conditional delivery rates) compare with the overall “unconditional” packet delivery rate in the first question? How independent or bursty were the losses

这一问是考察收包丢包的独立性,感觉像贝叶斯,逻辑是这样的:

  1. 所有收到的包就可分成两种:

    1. 前一个包是丢的
    2. 前一个包是收到的
  2. 每一个应该收到的 echo reply 包,可能收到了,也可能丢了

\(count(此包收到) = count(前一个包收到,此包也收到) + count(前一个包丢了,但是此包收到了)\)

在我自己的实验过程中,是后者占绝大多数。

\[\frac{count(此包收)}{包总数} = \frac{count(前包收,此包收)}{总包数} + \frac{count(前包丢,此包收)}{总包数} \\count(前包收,此包收) = 收包数 \times P(已知前包收,后包也收) \\count(前包丢,此包收) = 丢包数 \times P(已知前包丢,后包却收) \\\frac{count(此包收)}{包总数} \\ = P(收包) \\ = \frac{count(前包收,此包收)}{总包数} + \frac{count(前包丢,此包收)}{总包数} \\ = P(收包) \times P(已知前包收,后包也收) + P(丢包) \times P(已知前包丢,后包却收) \]

checkpoint5

通过 ARP 报文查询 ip 对应的 eth_addr 时候,ARP 报文中的 dst_eth_addr 字段为 0,而封装好的 frame 的 dst_eth_addr 字段为全 1

要先 queue 不知道 ip 地址的 datagram,再发送 arp 报文

checkpoint6

checkpoint 7

wsl 把代理关了是可以做的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/744288.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解锁网络无限可能:揭秘微软工程师力作——付费代理IP池深度改造与实战部署指南

"揭秘微软工程师力作:付费代理IP池深度改造,四大模块精讲,含实战部署指南。掌握高效、稳定代理IP资源,解锁网络无限可能。从筛选管理到安全加密,详细步骤助您快速搭建专属代理网络。尊享付费阅读,获取深度技术洞察与实践指导。"基于付费代理的代理IP池 项目来源…

SpringIOC 容器

SpringIOC 容器 一、组件的概念 什么是组件? 常规的三层架构处理请求流程:划分为组件后:组件就是所有可以重用的java对象,组件一定是对象,对象不一定是组件二、Spring 进行组件管理 Spring框架替代了程序员原有的new对象和对象属性赋值的动作组件对象实例化组件属性赋值组…

javap和字节码

javap字节码的基本信息public class Test {private int age = 10;public int getAge() {return age;} }在 class 文件的同级目录下输入命令 javap -v -p Test.class 来查看一下输出的内容// 字节码文件的位置 Classfile /D:/Code/code/JavaCode/JavaSourceLearn/out/production…

Prometheus之钉钉

要实现Prometheus通过Alertmanager发送告警到钉钉,您可以按照以下步骤进行配置:创建钉钉机器人:首先,您需要在钉钉群中添加一个自定义机器人,并获取机器人的Webhook地址。创建机器人时,您可以设置安全验证方式,如加签。创建完成后,保存好Webhook地址和加签后的秘钥(如…

Java——N以内累加求和

2024/07/15 1.题目 2.错误 3.分析 4.答案 1.题目2.错误 import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int N = scanner.nextInt();int sum = 0;while (N<=1000) {for (int i=1;i<=N;…

SQLCoder部署和应用

SQLCoder文生SQL部署和应用主页个人微信公众号:密码应用技术实战 个人博客园首页:https://www.cnblogs.com/informatics/SQLCoder简介 SQLCoder是一个用于生成SQL语句的工具,可以通过输入自然语言描述的需求,生成对应的SQL语句。SQLCoder支持连接数据库,对生成的SQL语句可…

NOIP 十三连测 #2 补题

逆天输出文件 .ans reverse 水题,随便自己造两组数据都能看出规律: \[\begin{cases}a_n a_{n - 2} \dots a_1 + a_2 a_4 \dots a_{n - 1}(n \mod 2 = 1) \\ a_n a_{n - 2} \dots a_2 + a_1 a_3 \dots a_{n - 1 } (n \mod 2 = 0)\end{cases} \]logistics 先求出最小生成树的 \…

MySQL时间戳转成日期格式

将时间戳转换为日期格式:-- 如果时间戳为毫秒级长度为13位,需要先除以1000 SELECT id, `task_name` ,FROM_UNIXTIME(`task_register_begin_time`/1000,%Y-%m-%d %H:%i:%s) as task_register_begin_time,FROM_UNIXTIME(`task_register_end_time`/1000,%Y-%m-%d %H:%i:%s) as t…

使用GSAP制作动画视频

GSAP 3Blue1Brown给我留下了深刻印象。利用动画制作视频,内容简洁,演示清晰。前两天刚好碰到一件事,我就顺便学习了一下怎么用代码做动画。 以javascrip为例,有两个动画引擎,GSAP和Animajs。由于网速的原因,询问了GPT后,我选择了GSAP来制作我的第一个动画视频。 制作动画…

log4cpp的安装及使用

介绍开源库log4cpp的安装及使用目录前言安装使用示例代码配置文件编译链接输出 前言 本文的操作均在ubuntu20.04下进行 安装 本文仅介绍从源码编译安装log4cpp的过程。 ①在开始编译前,首先要确保系统中安装了g++,make,autoconf和libtool ②下载log4cpp源码 下载log4cpp的特…

Intellij springboot远程调试

服务器端配置: java -jar -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=*:5005 XXXX.jar 说明: address:IP:端口;*代表所有IP地址都可访问,5005需要可IDEA远程请求的端口一致 XXXX.jar:你的springboot程序 IDEA端配置:

采购订单列表根据多条件设置单元格背景色

bos配置: 如果值存在空字符串和空格,空格会标红,为空不会。因此单独针对空字符串标红。 测试效果: