国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

CS144 計(jì)算機(jī)網(wǎng)絡(luò) Lab0:Networking Warmup

這篇具有很好參考價(jià)值的文章主要介紹了CS144 計(jì)算機(jī)網(wǎng)絡(luò) Lab0:Networking Warmup。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

前言

本科期間修讀了《計(jì)算機(jī)網(wǎng)絡(luò)》課程,但是課上布置的作業(yè)比較簡(jiǎn)單,只是分析了一下 Wireshark 抓包的結(jié)構(gòu),沒有動(dòng)手實(shí)現(xiàn)過(guò)協(xié)議。所以最近在嗶哩大學(xué)在線學(xué)習(xí)了斯坦福大學(xué)的 CS144 計(jì)算機(jī)網(wǎng)課程,這門課搭配了幾個(gè) Lab,要求動(dòng)手實(shí)現(xiàn)一個(gè) TCP 協(xié)議,而不是簡(jiǎn)單地調(diào)用系統(tǒng)為我們提供好的 Socket。

實(shí)驗(yàn)準(zhǔn)備

CS144 Fall2019 的課件和實(shí)驗(yàn)指導(dǎo)書可以下載自 CS144 鏡像網(wǎng)站,代碼可以從我的 Github 倉(cāng)庫(kù)獲取。

本篇博客將會(huì)介紹 Lab0 的實(shí)驗(yàn)過(guò)程,實(shí)驗(yàn)環(huán)境為 Ubuntu20.04 虛擬機(jī),使用 VSCode 完成代碼的編寫。

實(shí)驗(yàn)過(guò)程

Lab0 有兩個(gè)任務(wù),第一個(gè)任務(wù)是實(shí)現(xiàn)能發(fā)送 Get 請(qǐng)求到任意網(wǎng)址的 webget 程序,第二個(gè)任務(wù)是實(shí)現(xiàn)內(nèi)存內(nèi)的可靠字節(jié)流。

webget

實(shí)驗(yàn)指導(dǎo)書中讓我們先用 Telnet 程序連接到斯坦福大學(xué)的 Web 服務(wù)器上,在命令行中輸入 telnet cs144.keithw.org http 并回車,不出意外的話會(huì)提示已成功連接上服務(wù)器。之后手動(dòng)構(gòu)造請(qǐng)求報(bào)文,包括請(qǐng)求行和請(qǐng)求頭,輸入兩次回車就能得到響應(yīng),響應(yīng)體內(nèi)容為 Hello, CS144。

CS144 計(jì)算機(jī)網(wǎng)絡(luò) Lab0:Networking Warmup

應(yīng)用層的 Http 協(xié)議使用 TCP 傳輸層協(xié)議進(jìn)行數(shù)據(jù)的可靠性傳輸,由于我們目前還沒有實(shí)現(xiàn) TCP 協(xié)議,只能先借用一下操作系統(tǒng)寫好的的 socket 來(lái)發(fā)送 http 請(qǐng)求。CS144 的老師們十分貼心地對(duì) socket 庫(kù)進(jìn)行了二次封裝,類圖如下所示:

CS144 計(jì)算機(jī)網(wǎng)絡(luò) Lab0:Networking Warmup

FileDescriptor 的部分代碼如下,可以看到內(nèi)部類 FDWrapper 持有文件描述符,會(huì)在析構(gòu)的時(shí)候調(diào)用 close() 函數(shù)釋放對(duì)文件描述符的引用 。FileDescriptor 還提供了 read()write() 函數(shù)進(jìn)行文件讀寫操作:

class FileDescriptor {
    //! \brief A handle on a kernel file descriptor.
    //! \details FileDescriptor objects contain a std::shared_ptr to a FDWrapper.
    class FDWrapper {
      public:
        int _fd;                    //!< The file descriptor number returned by the kernel
        bool _eof = false;          //!< Flag indicating whether FDWrapper::_fd is at EOF
        bool _closed = false;       //!< Flag indicating whether FDWrapper::_fd has been closed

        //! Construct from a file descriptor number returned by the kernel
        explicit FDWrapper(const int fd);
        //! Closes the file descriptor upon destruction
        ~FDWrapper();
        //! Calls [close(2)](\ref man2::close) on FDWrapper::_fd
        void close();
    };

    //! A reference-counted handle to a shared FDWrapper
    std::shared_ptr<FDWrapper> _internal_fd;

  public:
    //! Construct from a file descriptor number returned by the kernel
    explicit FileDescriptor(const int fd);

    //! Free the std::shared_ptr; the FDWrapper destructor calls close() when the refcount goes to zero.
    ~FileDescriptor() = default;

    //! Read up to `limit` bytes
    std::string read(const size_t limit = std::numeric_limits<size_t>::max());

    //! Read up to `limit` bytes into `str` (caller can allocate storage)
    void read(std::string &str, const size_t limit = std::numeric_limits<size_t>::max());

    //! Write a string, possibly blocking until all is written
    size_t write(const char *str, const bool write_all = true) { return write(BufferViewList(str), write_all); }

    //! Write a string, possibly blocking until all is written
    size_t write(const std::string &str, const bool write_all = true) { return write(BufferViewList(str), write_all); }

    //! Close the underlying file descriptor
    void close() { _internal_fd->close(); }

    int fd_num() const { return _internal_fd->_fd; }        //!< \brief underlying descriptor number
    bool eof() const { return _internal_fd->_eof; }         //!< \brief EOF flag state
    bool closed() const { return _internal_fd->_closed; }   //!< \brief closed flag state
};

// 析構(gòu)的時(shí)候自動(dòng)釋放文件描述符
FileDescriptor::FDWrapper::~FDWrapper() {
    try {
        if (_closed) {
            return;
        }
        close();
    } catch (const exception &e) {
        // don't throw an exception from the destructor
        std::cerr << "Exception destructing FDWrapper: " << e.what() << std::endl;
    }
}

我們知道,在 Linux 系統(tǒng)中 “萬(wàn)物皆文件”,socket 也被認(rèn)為是一種文件,socket 被表示成文件描述符,調(diào)用 socket() 函數(shù)返回就是一個(gè)文件描述符,對(duì) socket 的讀寫就和文件的讀寫一樣。所以 Socket 類繼承自 FileDescriptor 類,同時(shí)擁有三個(gè)子類 TCPSocket、UDPSocketLocalStreamSocket,我們將使用 TCPSocket 完成第一個(gè)任務(wù)。

第一個(gè)任務(wù)需要補(bǔ)全 apps/webget.ccget_URL() 函數(shù),這個(gè)函數(shù)接受兩個(gè)參數(shù):主機(jī)名 host 和請(qǐng)求路徑 path

void get_URL(const string &host, const string &path) {
    TCPSocket socket;
    
    // 連接到 Web 服務(wù)器
    socket.connect(Address(host, "http"));
    
    // 創(chuàng)建請(qǐng)求報(bào)文
    socket.write("GET " + path + " HTTP/1.1\r\n");
    socket.write("Host: " + host + "\r\n\r\n");
    
    // 結(jié)束寫操作
    socket.shutdown(SHUT_WR);

    // 讀取響應(yīng)報(bào)文
    while (!socket.eof()) {
        cout << socket.read();
    }

    // 關(guān)閉 socket
    socket.close();
}

首先調(diào)用 connect() 函數(shù)完成 TCP 的三次握手,建立與主機(jī)的連接,接著使用 write() 函數(shù)手動(dòng)構(gòu)造請(qǐng)求報(bào)文。請(qǐng)求報(bào)文的格式如下圖所示,其中請(qǐng)求行的方法是 GET,URI 為請(qǐng)求路徑 path,Http 協(xié)議版本為 HTTP/1.1,而首部行必須含有一個(gè) Host 鍵值對(duì)指明將要連接的主機(jī):

CS144 計(jì)算機(jī)網(wǎng)絡(luò) Lab0:Networking Warmup

發(fā)送完請(qǐng)求報(bào)文后就可以結(jié)束寫操作,并不停調(diào)用 TCPSocket.read() 函數(shù)讀取響應(yīng)報(bào)文的內(nèi)容直至結(jié)束,最后關(guān)閉套接字釋放資源。其實(shí)這里也可以不手動(dòng)關(guān)閉,因?yàn)?socket 對(duì)象被析構(gòu)的時(shí)候會(huì)自動(dòng)調(diào)用 FDWrapper.close() 釋放文件描述符。

在命令行中輸入下述命令完成編譯:

mkdir build
cd build
cmake ..
make -j8

之后運(yùn)行 ./apps/webget cs144.keithw.org /hello 就能看到響應(yīng)報(bào)文了:

CS144 計(jì)算機(jī)網(wǎng)絡(luò) Lab0:Networking Warmup

接著運(yùn)行測(cè)試程序,也順利通過(guò)了:

CS144 計(jì)算機(jī)網(wǎng)絡(luò) Lab0:Networking Warmup

in-memory reliable byte stream

任務(wù)二要求我們實(shí)現(xiàn)一個(gè)內(nèi)存內(nèi)的有序可靠字節(jié)流:

  • 字節(jié)流可以從寫入端寫入,并以相同的順序,從讀取端讀取
  • 字節(jié)流是有限的,寫者可以終止寫入。而讀者可以在讀取到字節(jié)流末尾時(shí),不再讀取。
  • 字節(jié)流支持流量控制,以控制內(nèi)存的使用。當(dāng)所使用的緩沖區(qū)爆滿時(shí),將禁止寫入操作。
  • 寫入的字節(jié)流可能會(huì)很長(zhǎng),必須考慮到字節(jié)流大于緩沖區(qū)大小的情況。即便緩沖區(qū)只有1字節(jié)大小,所實(shí)現(xiàn)的程序也必須支持正常的寫入讀取操作。
  • 在單線程環(huán)境下執(zhí)行,無(wú)需考慮多線程生產(chǎn)者-消費(fèi)者模型下各類條件競(jìng)爭(zhēng)問題。

由于寫入順序和讀出順序相同,這種先入先出的 IO 特性可以使用隊(duì)列來(lái)實(shí)現(xiàn)。C++ 標(biāo)準(zhǔn)庫(kù)提供了 std::queue 模板類,但是 std::queue 不支持迭代器,這會(huì)對(duì)后續(xù)編碼造成一點(diǎn)麻煩,所以這里換成雙端隊(duì)列 std::deque。

類聲明如下所示,使用 deque<char> 存儲(chǔ)數(shù)據(jù),_capacity 控制隊(duì)列長(zhǎng)度,_is_input_end 代表寫入是否結(jié)束:

class ByteStream {
  private:
    size_t _capacity;
    std::deque<char> _buffer{};
    size_t _bytes_written{0};
    size_t _bytes_read{0};
    bool _is_input_end{false};
    bool _error{};  //!< Flag indicating that the stream suffered an error.

  public:
    //! Construct a stream with room for `capacity` bytes.
    ByteStream(const size_t capacity);

    //! Write a string of bytes into the stream. Write as many
    //! as will fit, and return how many were written.
    //! \returns the number of bytes accepted into the stream
    size_t write(const std::string &data);

    //! \returns the number of additional bytes that the stream has space for
    size_t remaining_capacity() const;

    //! Signal that the byte stream has reached its ending
    void end_input();

    //! Indicate that the stream suffered an error.
    void set_error() { _error = true; }

    //! Peek at next "len" bytes of the stream
    //! \returns a string
    std::string peek_output(const size_t len) const;

    //! Remove bytes from the buffer
    void pop_output(const size_t len);

    //! Read (i.e., copy and then pop) the next "len" bytes of the stream
    //! \returns a vector of bytes read
    std::string read(const size_t len) {
        const auto ret = peek_output(len);
        pop_output(len);
        return ret;
    }

    //! \returns `true` if the stream input has ended
    bool input_ended() const;

    //! \returns `true` if the stream has suffered an error
    bool error() const { return _error; }

    //! \returns the maximum amount that can currently be read from the stream
    size_t buffer_size() const;

    //! \returns `true` if the buffer is empty
    bool buffer_empty() const;

    //! \returns `true` if the output has reached the ending
    bool eof() const;

    //! Total number of bytes written
    size_t bytes_written() const;

    //! Total number of bytes popped
    size_t bytes_read() const;
};

類實(shí)現(xiàn):

ByteStream::ByteStream(const size_t capacity) : _capacity(capacity) {}

size_t ByteStream::write(const string &data) {
    size_t ws = min(data.size(), remaining_capacity());

    for (size_t i = 0; i < ws; ++i)
        _buffer.push_back(data[i]);

    _bytes_written += ws;
    return ws;
}

//! \param[in] len bytes will be copied from the output side of the buffer
string ByteStream::peek_output(const size_t len) const {
    auto rs = min(buffer_size(), len);
    return {_buffer.begin(), _buffer.begin() + rs};
}

//! \param[in] len bytes will be removed from the output side of the buffer
void ByteStream::pop_output(const size_t len) {
    auto rs = min(len, buffer_size());
    _bytes_read += rs;
    for (size_t i = 0; i < rs; ++i)
        _buffer.pop_front();
}

void ByteStream::end_input() { _is_input_end = true; }

bool ByteStream::input_ended() const { return _is_input_end; }

size_t ByteStream::buffer_size() const { return _buffer.size(); }

bool ByteStream::buffer_empty() const { return _buffer.empty(); }

bool ByteStream::eof() const { return buffer_empty() && input_ended(); }

size_t ByteStream::bytes_written() const { return _bytes_written; }

size_t ByteStream::bytes_read() const { return _bytes_read; }

size_t ByteStream::remaining_capacity() const { return _capacity - buffer_size(); }

之后重新 make -j8 編譯,make check_lab0 的測(cè)試結(jié)果如下,也是成功通過(guò)了全部的測(cè)試用例:

CS144 計(jì)算機(jī)網(wǎng)絡(luò) Lab0:Networking Warmup

后記

由于 Lab0 只是個(gè)熱身實(shí)驗(yàn),所以整體而言還是比較簡(jiǎn)單的,通過(guò)這個(gè)實(shí)驗(yàn),可以加深對(duì) Http 請(qǐng)求報(bào)文結(jié)構(gòu)的理解,同時(shí)對(duì) C++ 的 RAII 機(jī)制也會(huì)有更直觀的認(rèn)識(shí),以上~~文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-417813.html

到了這里,關(guān)于CS144 計(jì)算機(jī)網(wǎng)絡(luò) Lab0:Networking Warmup的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • CS144(2023 Spring)Lab 0:networking warmup(環(huán)境搭建 & webget & bytestream)

    CS144(2023 Spring)Lab 0:networking warmup(環(huán)境搭建 & webget & bytestream)

    最近心情非常郁悶,搓一個(gè)CS144玩玩吧,正好2023 spring出新版了。。。CS144的頭4個(gè)Lab(加上0是5個(gè)),一步步實(shí)現(xiàn)了一個(gè)TCP。在開始之前,我想貼一下Lab中的這句話: The lab documents aren’t “specifications”—meaning they’re not intended to be consumed in a one-way fashion. They’re written closer

    2024年02月11日
    瀏覽(17)
  • CS 144 Lab Four 收尾 -- 網(wǎng)絡(luò)交互全流程解析

    CS 144 Lab Four 收尾 -- 網(wǎng)絡(luò)交互全流程解析

    對(duì)應(yīng)課程視頻: 【計(jì)算機(jī)網(wǎng)絡(luò)】 斯坦福大學(xué)CS144課程 本節(jié)作為L(zhǎng)ab Four的收尾,主要帶領(lǐng)各位來(lái)看看網(wǎng)絡(luò)交互的整體流程是怎樣的。 這里以tcp_ipv4.cc文件為起點(diǎn),來(lái)探究一下cs144是如何實(shí)現(xiàn)整個(gè)協(xié)議棧的。 首先,項(xiàng)目根路徑中的 tun.sh 會(huì)使用 ip tuntap 技術(shù)創(chuàng)建虛擬 Tun/Tap 網(wǎng)絡(luò)設(shè)備

    2024年02月04日
    瀏覽(17)
  • 北京大學(xué)計(jì)算機(jī)網(wǎng)絡(luò)lab1——MyFTP

    北京大學(xué)計(jì)算機(jī)網(wǎng)絡(luò)lab1——MyFTP

    目錄 Lab目標(biāo) 一、知識(shí)補(bǔ)充 二、具體實(shí)現(xiàn) 1.數(shù)據(jù)報(bào)文格式和字符串處理 2.open函數(shù) 3.auth 4.ls 5.get和put 三、總結(jié) ps:本人靠著計(jì)網(wǎng)lab幾乎就足夠在就業(yè)行情并不好的23年找到自己滿意的工作了,計(jì)網(wǎng)lab的教程也非常給力,對(duì)我這種恐懼寫lab的菜狗都非常友好(本人寫lab3確實(shí)比較

    2024年02月07日
    瀏覽(35)
  • 《計(jì)算機(jī)網(wǎng)絡(luò)自頂向下》Wireshark實(shí)驗(yàn) Lab4 TCP

    《計(jì)算機(jī)網(wǎng)絡(luò)自頂向下》Wireshark實(shí)驗(yàn) Lab4 TCP

    《計(jì)算機(jī)網(wǎng)絡(luò)自頂向下》Wireshark Lab + 套接字編程作業(yè) + 雜項(xiàng)實(shí)驗(yàn)室編程作業(yè) 全實(shí)驗(yàn)博客鏈接 各位好 啊 學(xué)計(jì)算機(jī)想要學(xué)好真的還是挺難的 說(shuō)實(shí)話 科班學(xué)計(jì)算機(jī)如果想要花大量的時(shí)間去學(xué) 只能把平時(shí)的課程大部分時(shí)間不去上 如果班級(jí)管理嚴(yán)格或者說(shuō) 各種因素讓你不得不去上

    2023年04月09日
    瀏覽(39)
  • Wireshark IP實(shí)驗(yàn)—Wireshark Lab: IP v7.0(計(jì)算機(jī)網(wǎng)絡(luò)自頂向下第七版)

    Wireshark IP實(shí)驗(yàn)—Wireshark Lab: IP v7.0(計(jì)算機(jī)網(wǎng)絡(luò)自頂向下第七版)

    修改發(fā)送數(shù)據(jù)包的大小 跟蹤的地址為 www.ustc.edu.cn text{www.ustc.edu.cn} www.ustc.edu.cn 由于自己抓的包比較凌亂,分析起來(lái)比較復(fù)雜,所以使用作者的數(shù)據(jù)包進(jìn)行分析 Select the first ICMP Echo Request message sent by your computer, and expand the Internet Protocol part of the packet in the packet details window.Wh

    2024年02月04日
    瀏覽(18)
  • Wireshark HTTP實(shí)驗(yàn)—Wireshark Lab: HTTP v7.0(計(jì)算機(jī)網(wǎng)絡(luò)自頂向下第七版)

    Wireshark HTTP實(shí)驗(yàn)—Wireshark Lab: HTTP v7.0(計(jì)算機(jī)網(wǎng)絡(luò)自頂向下第七版)

    Is your browser running HTTP version 1.0 or 1.1? What version of HTTP is the server running? 瀏覽器與服務(wù)器的版本均為 H T T P / 1.1 HTTP/1.1 H TTP /1.1 。 What languages (if any) does your browser indicate that it can accept to the server? 能接受簡(jiǎn)體中文以及英文。 What is the IP address of your computer? Of the gaia.cs.umass.edu serv

    2024年02月08日
    瀏覽(19)
  • Wireshark TCP實(shí)驗(yàn)—Wireshark Lab: TCP v7.0(計(jì)算機(jī)網(wǎng)絡(luò)自頂向下第七版)

    Wireshark TCP實(shí)驗(yàn)—Wireshark Lab: TCP v7.0(計(jì)算機(jī)網(wǎng)絡(luò)自頂向下第七版)

    What is the IP address and TCP port number used by the client computer (source) that is transferring the file to gaia.cs.umass.edu? 根據(jù)數(shù)據(jù)包中的 tcp-ethereal-trace-1 ,其源 IP 地址為 192.168.1.102 192.168.1.102 192.168.1.102 ,端口號(hào)為 1162 1162 1162 。 What is the IP address of gaia.cs.umass.edu? On what port number is it sending and re

    2023年04月09日
    瀏覽(27)
  • CS144-Lab6

    在本周的實(shí)驗(yàn)中,你將在現(xiàn)有的 NetworkInterface 基礎(chǔ)上實(shí)現(xiàn)一個(gè)IP路由器,從而結(jié)束本課程。路由器有幾個(gè)網(wǎng)絡(luò)接口,可以在其中任何一個(gè)接口上接收互聯(lián)網(wǎng)數(shù)據(jù)報(bào)。路由器的工作是根據(jù) 路由表 轉(zhuǎn)發(fā)它得到的數(shù)據(jù)報(bào):一個(gè)規(guī)則列表,它告訴路由器,對(duì)于任何給定的數(shù)據(jù)報(bào): 發(fā)

    2024年02月09日
    瀏覽(18)
  • CS144--Lab1筆記

    CS144--Lab1筆記

    CS144——Lab1筆記 作為使用了版本管理的項(xiàng)目,開始新的開發(fā),當(dāng)然先要新建一個(gè)開發(fā)分支啦,可以用命令或者直接在IDE中GIT的圖形控制界面操作,太簡(jiǎn)單就不細(xì)說(shuō)。(我習(xí)慣命名:dev-lab1) 首先要從原始倉(cāng)庫(kù)合并Lab1的相關(guān)文件到本地倉(cāng)庫(kù),接著在build目錄下編譯。執(zhí)行下面的

    2024年02月20日
    瀏覽(20)
  • CS 144 Lab One -- 流重組器

    CS 144 Lab One -- 流重組器

    對(duì)應(yīng)課程視頻: 【計(jì)算機(jī)網(wǎng)絡(luò)】 斯坦福大學(xué)CS144課程 Lab 1 對(duì)應(yīng)的PDF: Lab Checkpoint 1: stitching substrings into a byte stream 這幅圖完整的說(shuō)明了CS144 這門實(shí)驗(yàn)的結(jié)構(gòu): 其中, ByteStream 是我們已經(jīng)在 Lab0 中實(shí)現(xiàn)完成的。 我們將在接下來(lái)的實(shí)驗(yàn)中分別實(shí)現(xiàn): Lab1 StreamReassembler :實(shí)現(xiàn)一個(gè)流

    2024年02月16日
    瀏覽(20)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包