CS144-lab0
代码参考
环境搭建:推荐使用Ubuntu
一、telnet使用
- 获取网页(http协议)
telnet cs144.keithw.org http
Trying 104.196.238.229...
Connected to cs144.keithw.org.
Escape character is '^]'.
GET /hello HTTP/1.1
Host: cs144.keithw.org
HTTP/1.1 200 OK
Date: Sat, 13 Nov 2021 03:32:18 GMT
Server: Apache
Last-Modified: Thu, 13 Dec 2018 15:45:29 GMT
ETag: "e-57ce93446cb64"
Accept-Ranges: bytes
Content-Length: 14
Content-Type: text/plain
Hello, CS144!
- 通过telnet与netcat搭建全双工通信
- netcat
netcat -v -l -p 9090
Listening on [0.0.0.0] (family 0, port 9090)
Connection from localhost 56596 received!
- telnet
telnet localhost 9090
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
- 发邮件(由于没有sunetid无法发送)
根据查询资料得到结果应该如下(//后为服务器回复):
telnet smtp-unencrypted.stanford.edu smtp
//220 smtp-unencrypted.stanford.edu
HELO mycomputer.stanford.edu
// 250 OK
MAIL FROM:<sunetid@stanford.edu>
// 250 sunetid@stanford.edu ... Sender ok
RCPT TO:<sunetid@stanford.edu>
// 250 sunetid@stanford.edu ... Recipient ok
DATA
// 354 Enter mall, end with "." on a line by itself
From: sunetid@stanford.edu
To: sunetid@stanford.edu
Subject: Hello from CS144 Lab 0!
hello
.
// 250 Message accepted for delivery
QUIT
// 221 smtp-unencrypted.stanford.edu closing connection
二、将telnet获取网页的功能用TCPSocket实现
准备工作
需要修改的代码路径:/home/cs144/sponge/apps/webget.cc
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).
TCPSocket socket{};
//建立连接
socket.connect(Address(host, "http"));
// request
socket.write("GET " + path + " HTTP/1.1\r\n");
socket.write("HOST: " + host + "\r\n");
socket.write("\r\n");
// request结束
socket.shutdown(SHUT_WR);
while (!socket.eof()) {
cout << socket.read();
}
socket.close();
return;
}
测试1
make && ./apps/webget cs144.keithw.org /hello
结果1
HTTP/1.1 200 OK
Date: Wed, 02 Aug 2023 07:49:44 GMT
Server: Apache
Last-Modified: Thu, 13 Dec 2018 15:45:29 GMT
ETag: "e-57ce93446cb64"
Accept-Ranges: bytes
Content-Length: 14
Content-Type: text/plain
Hello, CS144!
测试2
make check_webget
结果2
Testing webget...
Test project /home/zane/cs144/sponge/build
Start 28: t_webget
1/1 Test #28: t_webget ......................... Passed 0.47 sec
100% tests passed, 0 tests failed out of 1
Total Test time (real) = 0.48 sec
Built target check_webget
三、实现一个可靠传输的双向字节流
代码路径:/home/zane/cs144/sponge/libsponge/byte_stream.hh
// 仅修改了private中定义的变量,主要将缓存区改为list
class ByteStream {
private:
// Your code here -- add private members as necessary.
// list作为缓存
std::list<char> buf = {};
size_t size;
// 0, start, end
size_t read_cnt = 0;
size_t write_cnt = 0;
bool is_end = 0;
bool _error{}; //!< Flag indicating that the stream suffered an error.
public:
....
}
路径:/home/zane/cs144/sponge/libsponge/byte_stream.cc
#include "byte_stream.hh"
#include <algorithm>
#include <iterator>
#include <sstream>
#include <stdexcept>
// 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) : size(capacity) {}
size_t ByteStream::write(const string &data) {
// size为buf总大小,buf.size()为当前buf列表已使用的大小
int remain = size - buf.size();
int data_len = data.size();
int use_num = min(remain, data_len);
int i = 0;
for (i = 0; i < use_num; i++) {
buf.push_back(data[i]);
// 更新写入长度
write_cnt++;
}
// 返回写入字数长度
return i;
// size_t len = data.length();
// if (len > _capacity - _buffer.size()) {
// len = _capacity - _buffer.size();
// }
// _write_count += len;
// string s;
// s.assign(data.begin(), data.begin() + len);
// _buffer.append(BufferList(move(s)));
// return len;
}
//! \param[in] len bytes will be copied from the output side of the buffer
string ByteStream::peek_output(const size_t len) const {
// 返回buf中前min(len,size)个字符
string res;
int buf_size = buf.size();
int l = len;
int num = min(buf_size, l);
int i = 0;
for (auto it = buf.begin(); (it != buf.end())&&(i < num); i++, it++) {
res.push_back(*it);
}
return res;
// size_t length = len;
// if (length > _buffer.size()) {
// length = _buffer.size();
// }
// string s = _buffer.concatenate();
// return string().assign(s.begin(), s.begin() + length);
}
//! \param[in] len bytes will be removed from the output side of the buffer
void ByteStream::pop_output(const size_t len) {
int buf_size = buf.size();
int l = len;
int num = min(buf_size, l);
for (int i = 0; i < num; i++) {
buf.pop_front();
// 更新计数
read_cnt++;
}
// size_t length = len;
// if (length > _buffer.size()) {
// length = _buffer.size();
// }
// _read_count += length;
// _buffer.remove_prefix(length);
// return;
}
void ByteStream::end_input() { is_end = true; }
bool ByteStream::input_ended() const { return is_end; }
size_t ByteStream::buffer_size() const { return buf.size(); }
bool ByteStream::buffer_empty() const { return buf.size() == 0; }
// end of file:缓冲区为空并且输入结束
bool ByteStream::eof() const { return buffer_empty() && input_ended(); }
size_t ByteStream::bytes_written() const { return write_cnt; }
size_t ByteStream::bytes_read() const { return read_cnt; }
size_t ByteStream::remaining_capacity() const { return size - buf.size(); }
测试
make && make check_lab0
结果
[100%] Testing Lab 0...
Test project /home/zane/cs144/sponge/build
Start 23: t_byte_stream_construction
1/9 Test #23: t_byte_stream_construction ....... Passed 0.00 sec
Start 24: t_byte_stream_one_write
2/9 Test #24: t_byte_stream_one_write .......... Passed 0.00 sec
Start 25: t_byte_stream_two_writes
3/9 Test #25: t_byte_stream_two_writes ......... Passed 0.00 sec
Start 26: t_byte_stream_capacity
4/9 Test #26: t_byte_stream_capacity ........... Passed 0.00 sec
Start 27: t_byte_stream_many_writes
5/9 Test #27: t_byte_stream_many_writes ........ Passed 0.02 sec
Start 28: t_webget
6/9 Test #28: t_webget ......................... Passed 2.68 sec
Start 45: t_address_dt
7/9 Test #45: t_address_dt ..................... Passed 0.04 sec
Start 46: t_parser_dt
8/9 Test #46: t_parser_dt ...................... Passed 0.00 sec
Start 47: t_socket_dt
9/9 Test #47: t_socket_dt ...................... Passed 0.00 sec
100% tests passed, 0 tests failed out of 9
Total Test time (real) = 2.77 sec
[100%] Built target check_lab0
ps:在6/9 Test中卡了一下希望后面不会出现问题。