CS144 lab0 warmup

0x00 在一切之前

这章主要是实现一个wget熟悉一下http报文构造,还有就是根据给出的api,创建一个管道。这个管道具有一定的极限大小,可以在输入端写入,在输出端读出,输入端可以停止写入并阻止接下来的写入操作。当读入端读到末尾的时候,他会遇到eof,当遇到eof时就不能继续读入任何内容。虽然管道有其本身的极限大小,但是如果同时读入读出是相当于它可以传输无穷多的字符。

源码位于我的仓库https://github.com/Wood1314/CS144

0x01 webget

1.1 实现要求

使用HTTP的GET方法访问指定的url,并且将response全部输出。

1.2 具体实现

主要就是看代码熟悉一下实验里提供的TCPSocket类还有Address类等,然后利用connetct连接后,用write和read方法发送和接收报文即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
void get_URL(const string &host, const string &path) {
// Your code here.

// You will need to connect to the "http" service on
// the computer whose name is in the "host" string,
// then request the URL path given in the "path" string.

// Then you'll need to print out everything the server sends back,
// (not just one call to read() -- everything) until you reach
// the "eof" (end of file).
string payload;
string rsp;

payload = "GET " + path + " HTTP/1.1\r\n";
payload += "Host: " + host + "\r\n";
payload += "Connection: close\r\n\r\n";

cerr << "Function called: get_URL(" << host << ", " << path << ").\n";
TCPSocket fd;
fd.connect(Address(host, "http"));
fd.write(payload);
while (!fd.eof()) {
fd.read(rsp);
cout << rsp;
}
return;
}

刚开始写的时候犯了如下错误

  1. GET没有全部大写
  2. 输入结束时候应该再加一个\r\n 而我加了一个\n,最后导致返回包一直是400。

0x02 实现一个内存中的字节流

2.1 实验要求

这个部分实验给出了想实现的效果,以及api接口还有检测正确性的harness。在快写完不断报错的时候才发现自己误解了题意,真尴尬啊。写代码之前还是要把思路理清楚。简而言之要求和需要注意的点如下。

  1. 这个字节流具有一个最大的大小,称为capacity。当前字节流中的数据不能超过capacity的大小。一次性输入超过capacity大小的字符话,超过该大小的字符会被舍。
  2. 字节流抽象的来说具有读入和输出两个口,当读入达到capacity时便不能再读入,当字节流为空时就不能输出。
  3. 当输入端关闭之后,也就是执行了endInput函数后。字节流为空后字节流就会置为EOF,因为此时输入端已经不可能再输入字符,此时到达结尾就意味着字符流不可能再输出任何字符了。

2.2 自己犯的错误

1
2
3
4
5
6
7
8
9
10
size_t ByteStream::write(const string &data) {
size_t dataSize = data.size();
size_t writenSize = 0;
while (this->streamflow.size() +writenSize < this->streamCapacity && writenSize < dataSize) { // [1]
this->streamflow.push_back(data[writenSize]);
writenSize++;
}
this->bytesWriten += writenSize;
return writenSize;
}

在[1]处错误的用this->streamflow.size() +writenSize这两个值相加与字符流的最大容量相比。导致实际读入的最大长度变小了。我本意是想用原本字符流的大小与已经读入的大小相加 但实际上多此一举,直接用当前size和最大容量相比就可以了。

遇到的另一个问题是对于eof的理解不到位,因此看着测试用例的报错乱改。

-------------本文结束感谢您的阅读-------------
+ +