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,不然第九个测试用例不过。

posted @ 2022-04-09 16:54  warrens  阅读(234)  评论(0编辑  收藏  举报