lab2-TCPReceiver

lab2主要分为两项任务:WrappingInt32与TCPReceiver的实现。

一. WrappingInt32实现

  1. wrap-absolute seqno转为seqno
  2. wrap函数的实现较为简单,不过多细述。如下所示:

    WrappingInt32 wrap(uint64_t n, WrappingInt32 isn){
        return WrappingInt32(n%uint64_t(pow(2,32)))+isn;
    }
    
  3. unwrap-seqno转为absolute seqno
  4. unwrap的实现是本节lab的难点。在实现前首先明确几个认识:
    • checkpoint的取值范围为\(0\)~\(2^{64}-1\)中的任何数。
    • 首先, 根据当前序列号 n n n 和初始序列号 I S N ISN ISN 可以计算出两者的差值 d e l t a = n − I S N delta=n-ISN delta=n−ISN, 而实际的相对序列号应该是 A = { d e l t a + k ⋅ 2 32 ∣ k = 0 , 1 , . . . } A={delta+k\cdot2^{32}| k=0,1,...} A={delta+k⋅232∣k=0,1,...} 之中最接近检查点 c h e c k p o i n t checkpoint checkpoint 的一个.
      距离检查点更近的数字范围为 B = { c h e c k p o i n t − 2 31 + 1 ≤ x ≤ c h e c k p o i n t + 2 31 ∣ x ∈ Z } B={checkpoint-2^{31}+1\leq x\leq checkpoint+2^{31}|x\in Z} B={checkpoint−231+1≤x≤checkpoint+231∣x∈Z}. 而这里有一个比较特殊的情况, 即 c h e c k p o i n t − 2 31 checkpoint-2^{31} checkpoint−231 与 c h e c k p o i n t + 2 31 checkpoint+2^{31} checkpoint+231 据检查点的距离均为 2 31 2^{31} 231, 但根据实验指导中的说明 “In your TCP implementation, you’ll use the index of the last reassembled byte as the checkpoint”, 即检查点实际上是最后一个重排的字节序号, 而当前收到字节的序号理论上应该在检查点之后, 因此这里选择的是后者 c h e c k p o i n t + 2 31 checkpoint+2^{31} checkpoint+231.
      最后, 实际的相对序列号 r e s u l t result result 为 r e s u l t = A ∩ B result=A\cap B result=A∩B.

二. TCPReceiver实现

TCPReceiver的主要部分已经由之前lab1实现的StreamReassembler类完成了,在此lab中主要是处理段的接收,以及TCPSegment中ackno与window_size值的计算
  1. void segment_received(const TCPSegment &seg)
  2. 在该函数中要处理syn与fin为1时的情况,以及checkpoint的更新,最后将seqno与checkpoint输入重组器中。
  3. std::optional<WrappingInt32> ackno()
  4. 在流开始后调用该函数将返回seqno值,故需将stream index+1转为absolute seqno再通过wrap函数转为seqno
  5. size_t window_size()
  6. 调用该函数将返回窗口大小,即容量减去字节流中存储的字节数(不包括未组装的字节,因为实际上未组装字节也应在窗口内)

    仓库地址:https://gitlab.eduxiji.net/NScola/wuhaocs144/-/tree/master/libsponge

posted @ 2023-02-22 22:46  无糖百事  阅读(25)  评论(0)    收藏  举报