概述

image.png

  • 要求用一种模块化的方式实现TCP,上图是本实验的TCP实现的模块图(标注了数据流)
    • Lab0实现了ByteStream,在接下来的实验中你将用到它
      • “outbound”ByteStream,本地应用程序用它写入字节流数据,TCP将其中的数据发往对等实体
      • “inbound”ByteStream,写入从对等实体传过来的字节流数据,本地应用程序将从中读出数据
    • Lab1将实现StreamReassembler,用于将一段一段的数据(segments)按顺序拼接成一个完整字节流(这个是TCPReceiver的工作)
    • Labs2、3、4将实现TCPReceiver、TCPSender、TCPConnection(将TCPReceiver和TCPSender连接在一起)
    • Lab2将实现TCPReceiver,用于处理“inbound”ByteStream(TCP用序列号表示每个字节在字节流中的位置),TCPReceiver将负责告诉发送方
      • 已经有多少字节被成功接收并组装(ACK)
      • 目前还能再发多少字节的数据(接收窗口大小,用于流量控制)
    • Lab3将实现TCPSender,用于处理“outbound”ByteStream
      • 发送方怀疑报文段丢失的时候应该怎么处理?
      • 什么时候重传报文段?
    • Lab4将实现TCPConnection,综合使用前置实验的成果
      • 1个TCPConnection包含1个TCPSender和1个TCPReceiver
      • 你将用TCPConnection连接到任意的Web服务器

编写代码前的准备

你应该在Lab0的Sponge代码库的基础上实现本实验

  1. 确保在此之前已经commit了Lab0的内容(指git的commit?),之后就不要再修改webget.cc、libsponge/byte_stream.hh和libsponge/byte_stream.cc了
  2. 在项目目录下运行git fetch,确保代码是最新的
  3. 运行git merge origin/lab1-startercode
  4. cd build
  5. make -j4
  6. writeups/lab1.md是本实验的checkList,需要提交,请认真填写

    实现StreamReassembler

    概述

  • TCPSender会将数据分成一段一段的segment,或者说是substring
    • 每一段数据最大为1460字节
    • segment在网络中传输时,可能会乱序、丢失、重复
  • 所以,TCPReceiver必须将这些segments按原先的顺序重新组装成连续的字节流,本实验将实现StreamReassembler,用于实现这个功能
    • StreamReassembler有一个用于输出的ByteStream
    • 我觉得下图是一段废话,就不翻译了
    • image.png
  • 下图展示了StreamReassembler的接口

image.png

  • 构造函数,包含capacity参数

image.png

  • 尝试加入一段数据data,这里的数据应该已经去掉了TCP首部信息
  • index指的是当前data的第一个字节的序号(即字节流中的序号)
  • eof表示当前data的最后一个字节是否是字节流的最后一个字节

image.png

  • 返回组装后的字节流

image.png

  • 返回已经缓存,但未组装到字节流中的字节个数

image.png

  • 没有已缓存但是没有被组装的数据

  • 完整的接口描述在stream_reassembler.hh头文件中,你的任务就是实现这个类
  • 你可以添加任何的私有成员变量和私有方法,但是不能修改公有方法

    什么是“capacity”

  • 注意,你的push_substring方法需要忽略所有可能使得StreamReassembler超过其容量的数据部分

  • “capacity”:可存储的最大字节数
  • 在实现时,你应该将“capacity”视为如下两种数据的上界(注意是两种数据合起来不超过这个上界)
    • 已经被重新组装但还未被上层应用读取的字节流中的字节数(下图的绿色部分)
    • 已经接收但未被重新组装的字节流中的字节数(下图的红色部分)

image.png

FAQs

  • 流的第一个字节的序号?0
  • 我的实现需要关注效率问题吗?不需要,只要测试在半秒内结束就好了
  • 如果出现不一致的substrings该怎么办?可以假设不存在不一致的substrings,即所有的substrings可以组成1个唯一的完整的字节流
  • 我可以用什么?你可以用C++基础库中的任何东西,我们希望你能用到至少一个数据结构
  • 字节应该在什么时候写入流?As soon as possible
    • 只有当它前面的字节没有被push进来的时候,那个这个字节就不能写入
  • May substrings provided to the push_substring() function overlap?Yes
    • 这句话的意思应该是,调用push_substring传进来的string data这个参数,里面保存的数据可能是重叠的
    • 例如,一开始可能传进来[0,1)区间的数据是“a”,然后可能传进来[0,3)区间的数据“abc”,然后可能传进来[1,5)区间的数据“bcde”
    • 即两个数据串属于整个流的区间是重叠的
  • 我需要给StreamReassembler添加私有成员变量吗?需要,substrings可能乱序到达,所以你需要一个能够缓存substrings的数据结构,直到它们可以被按顺序放入流中

image.png

  1. 你可以在编译代码后运行指令make check_lab1进行测试
  2. 注意git的使用

image.png

  1. 注意代码的可读性,包括自解释的变量命名、注释;
    1. defensive programming,显式的检查函数的前置条件或不变量,必要的时候抛出异常

image.png

  1. 使用现代化的C++语法风格
    1. 你可能会用到move()函数来传递一个不可被copy的对象
  2. 如果产生一个segmentation fault

image.png

  1. reset the build system

image.png

提交注意事项

  • 仅修改libsponge顶级目录下的.hh和.cc文件,可以为对象添加私有成员,但不要修改公有接口
  • 在提交前,请按顺序运行
    • make format
    • make
    • make check_lab1
  • 编辑writeups/lab1.md,文档中需要包含
    • 程序设计结构
    • 实现过程中遇到的挑战
    • 未解决的BUG
  • 提交指南:https://cs144.github.io/submit