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