0%

cs144-lab0

简介

lab0 主要有四项任务,分别是使用 telnet 获取网页内容,使用 telnet 发送电子邮件,编写一个 webget 程序获取网页内容,以及完成一个读取内存字节流的程序。

1-2

按照实验手册的命令执行即可,命令之间的间隔时间不宜太长,否则服务器会报请求超时的错。

02
01
01

3 编写 webget

包括以下几步:新建 socket;与服务器建立连接;发送请求;读响应。关键代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
TCPSocket client_socket;
// 与服务器建立TCP连接
client_socket.connect(Address(host, "http"));
// 客户端发送请求request
string reqMsg = "GET " + path + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n";
client_socket.write(reqMsg);
// 客户端接收服务端的响应response
while (!client_socket.eof())
{
string recvMsg = client_socket.read();
cout << recvMsg;
}
client_socket.close();

4 完成一个读取内存字节流的程序

实验要求是完成对一个内存缓冲区中字符串的读和写任务。设置私有变量bytes作为缓冲区,并使用如下变量记录缓冲区大小,已读已写字符的大小等。

1
2
3
4
5
6
string bytes = "";
size_t maxsize = 0;
size_t hasread = 0;
size_t haswritten = 0;
bool is_end = false;
bool _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
ByteStream::ByteStream(const size_t capacity)
{
maxsize = capacity;
}
size_t ByteStream::write(const string &data)
{
size_t size;
if (data.size() <= remaining_capacity())
size = data.size();
else
size = remaining_capacity();
bytes += data.substr(0, size);
haswritten += size;
return size;
}
//! \param[in] len bytes will be copied from the output side of the buffer
string ByteStream::peek_output(const size_t len) const
{
size_t size;
if (len <= buffer_size())
size = len;
else
size = buffer_size();
string str = bytes.substr(0, size);
return str;
}
//! \param[in] len bytes will be removed from the output side of the buffer
void ByteStream::pop_output(const size_t len)
{
size_t size;
if (len <= buffer_size())
size = len;
else
size = buffer_size();
bytes.erase(0, size);
hasread += size;
}
//! 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)
{
size_t size;
if (len <= buffer_size())
size = len;
else
size = buffer_size();
string ret = peek_output(size);
pop_output(size);
return ret;
}
void ByteStream::end_input() { is_end = true; }
bool ByteStream::input_ended() const { return is_end; }
size_t ByteStream::buffer_size() const { return bytes.size(); }
bool ByteStream::buffer_empty() const { return bytes.empty(); }
bool ByteStream::eof() const { return buffer_empty() && is_end; }
size_t ByteStream::bytes_written() const { return haswritten; }
size_t ByteStream::bytes_read() const { return hasread; }
size_t ByteStream::remaining_capacity() const { return maxsize - bytes.size(); }

测试结果

测试结果如下,可通过所有测试点。

01