Lab0:Networking warmup
# Lab0:Networking warmup
lab0.pdf (cs144.github.io) (opens new window)
# 2 Networking by hand
# 2.1 Fetch a Web page
用 HTTP 协议获取一个网页页面
telnet cs144.keithw.org http
GET /lab0/12345 HTTP/1.1
Host: cs144.keithw.org
Connection: close
# 2.2 Send yourself an email
SMTP 协议的使用,我们可以用 QQ 邮箱来代替
参考:利用Telnet登录qq邮箱发送邮件——SMTP协议学习 (opens new window)
telnet smtp.qq.com 25
helo qq.com
auth login
xxxxxxxxx // QQ 邮箱的 base64 编码
xxxxxxxxx // 授权码的 base64 编码
mail from:<xxxxxxxxxx@qq.com>
rcpt to:<xxxxxxxxxx@qq.com>
data
From:xxx
To:xxx
Subject:xxx
空一行
<发送内容>
. (输入点代表编辑结束)
Test:
# 2.3 Listening and connecting
按文档操作即可。
# 3 Writing a network program using an OS stream socket
# 3.1 - 3.3
按文档操作即可。
# 3.4 Writing webget
用已经提供的 API,来进行对网页的拉取。
先用 TCP 建立连接,然后发送 HTTP 报文即可。
注意读取响应报文的时候要读到 EOF
才能结束。
void get_URL(const std::string &host, const std::string &path) {
// Your code here.
// You will need to connect to the "http" service on
// the computer whose name is in the "host" std::string,
// then request the URL path given in the "path" std::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).
const Address webserver(host, "http");
TCPSocket sock;
sock.connect(webserver); // 请求连接
std::string httpMessage = "GET " + path + " HTTP/1.1\r\n";
httpMessage += "Host: " + host + "\r\n";
httpMessage += "Connection: close\r\n\r\n";
sock.write(httpMessage); // 发送 HTTP 报文
while (!sock.eof()) { // 读取内容直到 EOF
auto recvd = sock.read();
std::cout << recvd;
}
// sock.close();
std::cerr << "Function called: get_URL(" << host << ", " << path << ").\n";
std::cerr << "Warning: get_URL() has not been implemented yet.\n";
}
# 4 An in-memory reliable byte stream
先在 byte_stream.hh
中定义相关变量,具体含义可以看注释。
这里我用的是 std::string 来作为缓冲区
// byte_stream.hh
private:
// Your code here -- add private members as necessary.
size_t cap; // 缓冲区容量
size_t have_written; // 已写字节数
size_t have_read; // 已读字节数
std::string buf; // 数据缓冲区
bool write_end; // 记录是否写结束
具体看代码吧,不是很难。
// byte_stream.cc
#include "byte_stream.hh"
// 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) : cap(capacity), have_written(0), have_read(0), buf{}, write_end(false) { }// 构造函数初始化
size_t ByteStream::write(const string &data) {
int cnt = 0; // 写入了多少字节
for (auto x : data) {
if (buf.size() >= cap) break; // 保证不超过 capacity
buf += x;
have_written += 1;
cnt += 1;
}
return cnt;
}
//! \param[in] len bytes will be copied from the output side of the buffer
string ByteStream::peek_output(const size_t len) const {
return std::string(buf.begin(), buf.begin() + std::min(buf.size(), 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 > buf.size()) {
set_error(); // 设置 error
return;
}
buf.erase(0, len);
have_read += 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) {
if (len > buf.size()) {
set_error(); // 设置 error
return "";
}
std::string res = std::string(buf.begin(), buf.begin() + len);
buf.erase(0, len);
have_read += len;
return res;
}
void ByteStream::end_input() {
write_end = true;
}
bool ByteStream::input_ended() const {
return write_end;
}
size_t ByteStream::buffer_size() const {
return buf.size();
}
bool ByteStream::buffer_empty() const {
return buf.empty();
}
bool ByteStream::eof() const {
return buf.empty() && write_end;
}
size_t ByteStream::bytes_written() const {
return have_written;
}
size_t ByteStream::bytes_read() const {
return have_read;
}
size_t ByteStream::remaining_capacity() const {
return cap - buf.size();
}
# 实验结果
Last Updated: 4/1/2024, 7:57:33 AM