cs144 lab0
1.环境搭建,按照pdf搭建。
最好环境和他一样,注意不要用wsl,最后check_lab0的时候,第九个测试用例会failed。
2.手动连接网络
下面两项任务都是依赖一个可靠的字节流的(网络层交付过程是不可靠的,他只是尽力交付,使它可靠的是协议比如tcp)
2.1 手动获取一个网站
打开终端,输入telnet cs144.keithw.org http
利用telnet程序建立一个本地机器和远程服务器之间的可靠字节流,并且告诉它是http协议。
输入GET /hello HTTP/1.1
告诉服务url部分
输入Host: cs144.keithw.org
告诉服务host path
输入Connection: close
告诉服务你已经完成请求了,服务不久将会返回一个响应(这里要输入两个回车,上面每步结束输入一个回车)
然后就能看见响应了。(3那里的webget,用TCPSocket建立连接也是这么个流程)
2.2 发邮件(没做)
2.3监听和连接
在一个终端上输入,netcat -v -l -p 9090
,在localhost:9090进行监听
打开另外一个终端,输入 telnet localhost 9090
申请访问localhost:9090
在一个终端上任何输入(按下回车),内容都会出现在另外一个终端上,退出一个终端的服务(ctrl+c),另外一个终端的服务也退出了。
3.写一个简单socker程序
3.1按照lab说明把环境搭好。
3.2看下现代c++文档
3.3看Sponge文档
3.4编写一个webget程序(看hint,这里要注意在http中,/r/n表示换行)
具体代码如下
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 socket1;
socket1.connect(Address(host,"80"));
//这两个字段是类似上面2.1实验的
auto request = "GET "+path+" HTTP/1.1\r\n"+"Host: "+host+"\r\n";
auto request_close = "Connection: close\r\n\r\n";
socket1.write(request + request_close);
//获得响应
while(!socket1.eof()){
cout << socket1.read();
}
socket1.close();
}
4.实现一个可靠字节流
/libsponge 下有两个文件 byte_stream.hh byte_stream.cc ,.hh后缀的文件定义了方法,.cc要实现他
具体代码如下
.hh下
// Your code here -- add private members as necessary.
std::string buf;
size_t cap;
size_t total_wirte;
size_t total_read;
bool is_eof;
.cc下
ByteStream::ByteStream(const size_t capacity) :
buf(string("")),
cap(capacity),
total_wirte(0),
total_read(0),
is_eof(false) {}
size_t ByteStream::write(const string &data) {
size_t rest_cap = this->cap - this->buf.size();
if(rest_cap >= data.size()){
buf += data;
total_wirte += data.size();
return data.size();
}else{
buf += data.substr(0,rest_cap);
total_wirte += rest_cap;
return rest_cap;
}
}
//! \param[in] len bytes will be copied from the output side of the buffer
string ByteStream::peek_output(const size_t len) const {
string str = buf.substr(0,len);
return str;
}
//! \param[in] len bytes will be removed from the output side of the buffer
void ByteStream::pop_output(const size_t len) {
buf.erase(0,len);
total_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) {
size_t read_size = buf.size()>len?len:buf.size();
string read_str = peek_output(read_size);
pop_output(read_size);
return read_str;
}
void ByteStream::end_input() {
this->is_eof = true;
}
bool ByteStream::input_ended() const { return is_eof; }
size_t ByteStream::buffer_size() const { return buf.size(); }
bool ByteStream::buffer_empty() const { return buf.size() == 0; }
bool ByteStream::eof() const { return is_eof && buffer_empty(); }
size_t ByteStream::bytes_written() const { return total_wirte; }
size_t ByteStream::bytes_read() const { return total_read; }
size_t ByteStream::remaining_capacity() const { return cap - buf.size(); }
这里要注意这个pop函数也会要total_read增加,主要不要用wsl,不然第九个测试用例不过。