Frdmu's Space


Welcome to frdmu's space!


TCP Implementation

Lab 0

Part A : Writing webget

Ideas

  TCPSocket 是一个文件描述符,所以可以把Socket看做一个文件,webget 主要过程如下:

  • 与目标主机建立联系
  • 发出请求
  • 接受反馈
  • 关闭连接

Pics

Part B : An in-memory reliable byte stream

Ideas

  由于字节流一端输入,一端输出,所以用双端队列表示。需要注意的有以下几点:

// 写入字节流时,写入的大小应该取数据大小和字节流剩余容量的较小值 
size_t n = min(data.size(), remaining_capacity());
// Writer可以自己停止输入
void ByteStream::end_input() {}
// Reader查看字节流中len长度的数据
string ByteStream::peek_output(const size_t len) const {} 

// Reader弹出字节流中len长度的数据
void ByteStream::pop_output(const size_t len) {}

// Reader读取字节流中len长度的数据,实际上是先查看再弹出
std::string ByteStream::read(const size_t len) {}

Pics

Reference: lab0

Lab1

Putting substrings in sequence

Ideas

  主要难点是如何保存未被组装的字节流片段。解决方法是按字节存储,而不是按字节流片段存储。这样可以避免出现繁杂的情况。

void StreamReassembler::push_substring(const string &data, const size_t index, const bool eof) {
      
    if (index < neededIndex) {
        // 将>=neededIndex的部分存入未被组装的部分(未被组装的部分用tmpMap表示) 
    }
    if (index > neededIndex) {
        // 将data存入未被组装的部分 
    }
    if (index == neededIndex) {
        // 将data写入字节流
    }

    while (tmpMap.count(neededIndex) != 0) {
        // 在未被组装的部分寻找可以写入字节流的字节 
    }
}

Pics

Reference: lab1

Lab 2

Part A :Translating between 64-bit indexes and 32-bit seqnos

Ideas


// 64bit -> 32bit
// 思路:序列号的起点 + 偏移
// 序列号的起点就是isn
// 偏移则是 (n-0) % (2^32)
// 所以最后的结果是: isn + n % mod 
WrappingInt32 wrap(uint64_t n, WrappingInt32 isn) { 
    uint64_t mod = 1ul << 32; 
    n = n % mod; 
    return isn + static_cast<uint32_t>(n); 
} 

// 32bit -> 64bit
// 思路:绝对序列号的起点 + 偏移
// 1.首先找到距离checkpoint最近的2^32的倍数, 记为closetCheckpoint, 比如0,2^32, 2^33, 2^34....
// 2.然后计算偏移 offset = n-isn,
//   如果offset < 2^31,则closestCheckpoint是绝对序列号中的起点,
//   否则,closetCheckpoint-mod 是绝对序列号中的起点;
//   还有一种特殊情况,如果closestCheckpoint == 0, closestCheckpoint 只能是绝对序列号中的起点。
//   所以最后结果是: 绝对序列号的起点 + offset
uint64_t unwrap(WrappingInt32 n, WrappingInt32 isn, uint64_t checkpoint) { 
     // DUMMY_CODE(n, isn, checkpoint); 
     uint64_t mod = 1ul << 32; 
     uint64_t closestCheckpoint = (checkpoint + (1ul << 31)) / mod * mod; 
     uint64_t res = 0; 
     uint64_t offset = n.raw_value() - isn.raw_value(); 
      
     if (closestCheckpoint == 0) { 
         return offset; 
     } 
     if (offset < (1ll << 31)) { 
         res = closestCheckpoint + offset; 
     } else { 
         res = closestCheckpoint - mod + offset; 
     } 
  
     return res; 
} 

Pics

Reference: lab2