CS144LAB0 实验过程 超详细

发布于:2022-12-10 ⋅ 阅读:(1030) ⋅ 点赞:(0)

CS 144: Introduction to Computer Networking

目录

1 实验环境

2 Networking by hand

2.1 Fetch a Web page

2.2 Send yourself an email

2.3 Listening and connecting

3 Writing a network program using an OS stream socket

4 An in-memory reliable byte stream


1 实验环境

官方文档提供了三种支持运行该 Lab 的选择,我选择了VMware和Ubuntu18.04。下载,安装,配置共享文件夹不再赘述。

2 Networking by hand

这部分内容比较简单,跟着文章步骤即可。2.1手工获取一个网页;2.2 手工发送电子邮件;2.3 完成一个双工通信。

2.1 Fetch a Web page

1.通过浏览器访问网站  http://cs144.keithw.org/hello,可以看到以下信息:

 2. 在ubuntu终端,手动访问页面并观察结果

 命令输入的时候要快一些,不然会Timeout,如下:

 3. 访问网站 http://cs144.keithw.org/lab0/sunetid ,返回一个密码。这里编的sunetid 2022。

 2.2 Send yourself an email

这部分的实验内容是用终端登上QQ邮箱服务器(官方文档用的是斯坦福校内服务器),向另一个邮箱发一封邮件。

登陆QQ邮箱服务器需要输入邮箱的 base64 编码( xxxxxx@qq.com 的base64编码)                 输入开启 IMAP/SMPT 时授权码的 base64 编码(授权码无空格)

转码工具:https://www.qqxiuzi.cn/bianma/base64.htm

邮箱授权码获取步骤:https://blog.csdn.net/lzh1415926/article/details/122241446

 实验结果:

2.3 Listening and connecting

这部分的实验内容是两个终端可以相互通信,在终端1输入信息,终端2会显示,反之亦然。

3 Writing a network program using an OS stream socket

从这一部分开始需要编写c++代码。需要先配置一下IDE,本试验使用了VScode,安装教程如下:

基于Ubuntu的VScode下载安装教程_纯粹.的博客-CSDN博客_ubuntu下载vscode

3.1 按步骤先构建程序,暂不赘述。

3.2- 3.3 是讲述实验基础的一些内容,浅看一下即可。

3.4 webget.cc是为了使用Sponge中提供的基础类完成一个简单HTTP请求的发送并将返回的请求打印出来。(可以理解为用编程来实现2.1.2的内容)。实验过程如下:

1) 首先进入sponge文件夹,输入code . 会自动打开VScode编译器。

2) 在/apps/webget.cc 下,完成get_URL函数。

 

具体代码及注释如下:

void get_URL(const string &host, const string &path) {
    Address address(host, "http"); //传入主机的host 和需要的服务
    TCPSocket socket; //创建一个socket对象
    socket.connect(address);    // socket对象和服务器连接
    // 利用字符串拼接,参考2.1.2构建一个http请求报文
    socket.write("GET " + path + " HTTP/1.1\r\n"); // \r\n 表示回车
    socket.write("HOST: " + host + "\r\n");
    socket.write("\r\n");
    socket.shutdown(SHUT_WR);     // request结束
    // content
    while (!socket.eof()) {      //如果管道没有关,持续读输入进来的数据
        std::cout << socket.read(1);
    }
    socket.close();     // 关闭socket
}

3) 再次访问网站,得到回复Hello, CS144!

 

4) 用其他网站案例测试一下:

 100%通过,实验完成。

4 An in-memory reliable byte stream

这部分实验内容是写一个在内存中的可靠字节流。就是类似于读/写缓冲器的东西,提供了接口形式去实现就行了。这里使用了 deque 双向队列。双向队列支持头尾读写,刚好对应字节流从尾部写入从头部读取的特性,并且拥有迭代器,完美支持了该字节流类中的 peek 操作。

需要编写代码的两个文件分别为:

 .h 文件:

#ifndef SPONGE_LIBSPONGE_BYTE_STREAM_HH
#define SPONGE_LIBSPONGE_BYTE_STREAM_HH

#include <string>
#include <deque>
//! \brief An in-order byte stream.

class ByteStream {
  private:
     size_t max_capacity = 0;  //缓冲区最大容量
     size_t _bytes_written = 0;  //输入端写入的长度
     size_t _bytes_read = 0; // 输出端读取的长度
     std :: deque<char> _buf{}; //缓冲区队列

     bool is_end = false;
     bool _error = false;  //!< Flag indicating that the stream suffered an error.

  public:
后边不需要改,所以略去

.c 文件

#include "byte_stream.hh"
template <typename... Targs>
void DUMMY_CODE(Targs &&... /* unused */) {}

using namespace std;

//初始化字节流数据,设置缓冲区的最大容量
ByteStream::ByteStream(const size_t capacity) {
    max_capacity = capacity;
}

// 输入端写数据,存入到缓冲队列中
size_t ByteStream::write(const string &data) {
    // 如果队列满了 返回 0;
    if(remaining_capacity() == 0) return 0; 
    size_t write_size = (data.size() <= remaining_capacity()) ? data.size() : remaining_capacity();
    for(size_t i = 0; i < write_size; i ++)
    {
        _buf.push_back(data[i]);
    }
    _bytes_written += write_size;
    return write_size;
}

//! \param[in] len bytes will be copied from the output side of the buffer
// 查看缓冲区的队列内容,但是不出列
string ByteStream::peek_output(const size_t len) const {
    // DUMMY_CODE(len);
    // return {};
    size_t buf_size = (len <= buffer_size()) ? len : buffer_size();
    string data;
    data.assign(_buf.begin(), _buf.begin() + buf_size);
    return data;
}

//! \param[in] len bytes will be removed from the output side of the buffer
// 出队列,从缓冲区删除len长度的数据
void ByteStream::pop_output(const size_t len) {
    // DUMMY_CODE(len);
    size_t buf_size = (len <= buffer_size()) ? len : buffer_size();
    for(size_t i = 0; i < buf_size; i ++)
    {
        _buf.pop_front();
    }
    _bytes_read += buf_size;
}

//从缓冲区读出长度为len的数据
std::string ByteStream::read(const size_t len) {
    string buf_read = peek_output(len);
    pop_output(len);
    return buf_read;
}

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

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

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 max_capacity - _buf.size(); }

实验结果:

  100%通过,实验完成。


Ubuntu总是断网怎么重连:

Ubuntu 无法联网 解决办法_好人好事代表nxx的博客-CSDN博客

本文含有隐藏内容,请 开通VIP 后查看