抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

前言

cs144的lab文档非常详细,非常详细,详细到每一个都有10几页的大小,像一个仓库的readme,以至于菜狗花大量时间读机翻却没看明白到底要干些什么,这也导致在开始lab0时根本不清楚自己要干些什么。无论如何,这是一个很值得写完的lab。

Lab0

webget

webget.cc实现一个webget,实现访问外部网页。

需要使用TCPSocketAddress

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
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).
Address addr(host, "http");
TCPSocket st;
st.connect(addr);
st.write("GET " + path + " HTTP/1.1\r\n");
st.write("HOST: " + host + "\r\n");
st.write("Connection: close\r\n");
st.write("\r\n");
while(!st.eof()) {
cout << st.read();
}
st.close();

cerr << "Function called: get_URL(" << host << ", " << path << ").\n";
cerr << "Warning: get_URL() has not been implemented yet.\n";
}

byte_stream

需要实现一个可靠byte流。

大致需求:

  1. 需要限制缓冲区长度,在缓冲区未满时才能写入缓冲区

  2. 字节流可以无限长

  3. 它是单线程的,不用考虑并发

无非就是维护一个bytestream数据结构。

1
2
3
4
5
6
7
8
9
10
class ByteStream {
private:
std::string _buffer;
size_t _capacity = 0;
size_t _read_count = 0;
size_t _write_count = 0;
bool _input_end_flag = false;
bool _error = false; //!< Flag indicating that the stream suffered an error.

...

byte_stream.cc

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
ByteStream::ByteStream(const size_t capacity) : _buffer(), _capacity(capacity) {}

size_t ByteStream::write(const string &data) {
size_t cc = 0;
for (size_t i = 0; i < data.size() && remaining_capacity() > 0; ++i, ++_write_count, ++cc)
_buffer.push_back(data[i]);

return cc;
}

//! \param[in] len bytes will be copied from the output side of the buffer
string ByteStream::peek_output(const size_t len) const { return _buffer.substr(0, len); }

//! \param[in] len bytes will be removed from the output side of the buffer
void ByteStream::pop_output(const size_t len) {
if (len >= buffer_size()) {
_read_count += buffer_size();
_buffer.clear();
} else {
_read_count += len;
_buffer.erase(0, len);
}
}

//! Read (i.e., copy and then pop) the next "len" bytes of the stream
//! \param[in] len bytes will be popped and returned
//! \returns a string
std::string ByteStream::read(const size_t len) {
string data = this->peek_output(len);
this->pop_output(len);
return data;
}

void ByteStream::end_input() { _input_end_flag = true; }

bool ByteStream::input_ended() const { return _input_end_flag; }

size_t ByteStream::buffer_size() const { return _buffer.size(); }

bool ByteStream::buffer_empty() const { return _buffer.size() == 0; }

bool ByteStream::eof() const { return buffer_empty() && input_ended(); }

size_t ByteStream::bytes_written() const { return _write_count; }

size_t ByteStream::bytes_read() const { return _read_count; }

size_t ByteStream::remaining_capacity() const { return _capacity - _buffer.size(); }

评论