CS144 Lab 0

[TOC]

1. The webget

在这个任务中,我们需要去利用cs144的库函数去写一个请求获取相应的网页。

大概就是手写报文的意思…

先过一遍流程

  1. 设置请求的地址和方法,host已经提供,方法为http
  2. 使用TCP建立连接
  3. 发送请求报文
  4. 输出,知道得到结束符
  5. 关闭连接

The code maybe look like this…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void get_URL(const string &host, const string &path) {
// Your code here.
TCPSocket socket;
socket.connect(Address(host, "http"));
socket.write("GET " + path + " HTTP/1.1\r\n");
socket.write("HOST: " + host + "\r\n");
socket.write("Connection: close\r\n");
socket.write("\r\n");
while (!socket.eof()) {
cout << socket.read();
}
socket.close();

// 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).

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

2. The byte_stream

2.1 request

  1. 读入数据
  2. 输出数据
  3. 有容量限制
  4. 能控制是否结束

2.2 new members

数据的输入端和输出端是在不同的位置的,所以我们使用deqeue这种数据结构…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class ByteStream {
private:
// Your code here -- add private members as necessary.

// Hint: This doesn't need to be a sophisticated data structure at
// all, but if any of your tests are taking longer than a second,
// that's a sign that you probably want to keep exploring
// different approaches.
std::deque<char> _data; // storage the data
size_t _bytes_written;
size_t _bytes_read;
size_t _capacity; // the capacity
bool _end_input; // make whether the stream has ended
bool _error{}; //!< Flag indicating that the stream suffered an error.

函数的实现

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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

// Dummy implementation of a flow-controlled in-memory byte stream.

// For Lab 0, please replace with a real implementation that passes the
// automated checks run by `make check_lab0`.

// You will need to add private members to the class declaration in `byte_stream.hh`

template <typename... Targs>
void DUMMY_CODE(Targs &&... /* unused */) {}

using namespace std;

ByteStream::ByteStream(const size_t capacity):
_data(),
_bytes_written(0),
_bytes_read(0),
_capacity(capacity),
_end_input(0),
_error(0)
{}

size_t ByteStream::write(const string &data) {
if (_end_input) return 0;
size_t can_write = min(data.size(), _capacity - _data.size());
_bytes_written += can_write;
for (size_t i = 0; i < can_write; i++) {
_data.push_back(data[i]);
}
return can_write;
}

//! \param[in] len bytes will be copied from the output side of the buffer
string ByteStream::peek_output(const size_t len) const {
int can_peek_output = min(len, _data.size());
return string(_data.begin(), _data.begin() + can_peek_output);
}

//! \param[in] len bytes will be removed from the output side of the buffer
void ByteStream::pop_output(const size_t len) {
size_t can_pop_output = min(len, _data.size());
_bytes_read += can_pop_output;
for (size_t i = 0; i < can_pop_output; i++) _data.pop_front();
}

//! 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) {
int can_read = min(_data.size(), len);
string _read = peek_output(can_read);
pop_output(can_read);
return _read;
}

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

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

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

bool ByteStream::buffer_empty() const {
return _data.empty();
}

bool ByteStream::eof() const {
return _end_input&&_data.empty();
}

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

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

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

2.3 test

image-20220611175820239