Yra's blog Yra's blog
Homepage
  • LeetCode周赛
  • Acwing周赛
  • 刷题整理
  • 题解
  • CPP
  • Golang
  • System

    • MIT6.S081 Labs
  • Computer Networking

    • CS144: Computer Networking
  • DataBase

    • MySQL
    • Redis
  • Others

    • ......
  • Paper Reading

    • Petri Net
  • Static Analysis

    • NJU Course Notes
  • Deep Learning

    • Dive into Deep Learning
Casual Records
Archives

Yra

Only a vegetable dog.
Homepage
  • LeetCode周赛
  • Acwing周赛
  • 刷题整理
  • 题解
  • CPP
  • Golang
  • System

    • MIT6.S081 Labs
  • Computer Networking

    • CS144: Computer Networking
  • DataBase

    • MySQL
    • Redis
  • Others

    • ......
  • Paper Reading

    • Petri Net
  • Static Analysis

    • NJU Course Notes
  • Deep Learning

    • Dive into Deep Learning
Casual Records
Archives
  • System

  • Computer Networking

    • CS144:Computer Networking

      • Lab0:Networking warmup
        • Lab1:stitching substrings into a byte stream
        • Lab2:The TCP Receiver
        • Lab3:The TCP Sender
        • Lab4:The TCP Connection
    • DataBase

    • Software Engineering

    • Others

    • Learning Notes
    • Computer Networking
    • CS144:Computer Networking
    Yra
    2023-03-10
    目录

    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:

    image-20230310232829857

    # 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();
    }
    

    # 实验结果


    image-20230311172536985
    #Learning Notes#Computer Networking#CS144:Computer Networking
    Last Updated: 4/1/2024, 7:57:33 AM
    Lab10: Mmap
    Lab1:stitching substrings into a byte stream

    ← Lab10: Mmap Lab1:stitching substrings into a byte stream→

    最近更新
    01
    408 计组笔记
    07-19
    02
    Dive into Deep Learning
    01-27
    03
    25 考研随记
    11-27
    更多文章>
    Theme by Vdoing | Copyright © 2022-2025
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式