CS144 Lab2

具体实现细节请参考 我的实现

Lab2 Start

这个实验要求实现一个TCPReceiver类

这个类是基于前两个实验,所以要熟悉前两个实验完成的接口

越靠后的实验,越是在封装上进行编程,如果忘记了,记得回去看接口

从这个实验开始,我们就真正设计到tcp协议中的内容,包括但不限于标志位,重发等机制

以下是各种标志位的意义

SYN (Synchronize) - 同步序列号

用于建立连接 ACK (Acknowledgment) - 确认标志 用于确认收到数据 RST (Reset) - 重置标志 重置连接

在一个tcp连接中可以同时有多个标志位,上述只是大致阐述,但在实现中仍旧有很多值的注意的细节

(预告:在Lab3中你将要同时处理各种标志位带来的情况)

TCPReceiver

接收函数

void TCPReceiver::receive( TCPSenderMessage message );

这个函数功能很清晰明了,提供一个TCPSenderMessage,我们需要进行解析,并且推送到**流重组器接口*

那么思路也是十分简单,但是要注意处理结构体TCPSenderMessage中的标志位

但是接收信息还需要记录isn,和维护状态

  std::optional<Wrap32> isn_ {};
  bool synced_ {};

需要在私有成员中添加这两个成员变量

程序的思路是这样的:

收到SYN的数据包后,就设置isn(起始seqno)

(在这个过程中SYN和FIN包都可以携带payload)

随后根据isn计算abs_seqno,计算first_index -> 流重组器接口需要

最后写入流重组器

void TCPReceiver::receive( TCPSenderMessage message )
{
  if ( message.RST ) {
    reassembler_.reader().set_error();
  }
  if ( message.SYN ) {
    isn_ = message.seqno;
    synced_ = true;
  }
  if ( !synced_ )
    return;

  uint64_t checkpoint = reassembler_.writer().bytes_pushed();
  uint64_t abs_seqno = message.seqno.unwrap( isn_.value(), checkpoint );

  uint64_t first_index = ( message.SYN ) ? 0 : abs_seqno - 1;
  reassembler_.insert( first_index, std::move( message.payload ), message.FIN );
}

需要结合理解的就是checkpoint和abs_seqno的计算,结合前面Lab1的笔记理解它的封装和设计思路

可以参考这个博客,讲述很清晰

send()函数

⋅˚₊‧ ⌜ on this page ⌟ ‧₊˚ ⋅

recent-work

并行, 异步和并发

TL;DR 这三个词经常被混着用,但它们回答的是三个不同的问题:并发问的是「同时有几个任务在飞」,并行问的是「有几个核真的在同时执行」,异步问的是「等一个慢操作的时候,要不要把线程也一起停住」。 本文先用手写一个有栈协程把「让出」这件事拆到底层(切换到 rsp 和几个 …

Read more →

ELF格式解析

TL;DR 一个 ELF 文件同时被四个角色读写:编译器产出它、链接器改造它、内核加载器消费它、工具与攻击者审视它。这四个读者看的是同一坨字节,但需求完全不同。ELF 的解法是把文件切成两套正交的索引表: Program Header Table(段视图)——给加载器看,描述“运 …

Read more →