栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

【计算机网络】cs144

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【计算机网络】cs144

【计算机网络】cs144
  • Lab0
    • A network program using an OS stream socket
    • A in-memory reliable byte stream
  • Lab1
    • Putting substrings in sequence
  • Lab2
  • Lab3
  • Lab4

Lab0 A network program using an OS stream socket

用操作系统的接口实现socket:创建一个TCP字节流socket,跟Web server发起连接,请求网页。socket编程是面向两台不同计算机的进程之间的字节流通信,socket类似于file descriptor。

// webget.cc

void get_URL(const string &host, const string &path) {
    TCPSocket sock;
    sock.connect(Address(host, "http"));
    sock.write("GET "+path+" HTTP/1.1rn");
    sock.write("Host: " + host + "rn");
    sock.write("Connection: closernrn");
    sock.shutdown(SHUT_WR);
    while(!sock.eof()){
        cout << sock.read();
    }
    sock.close();
}
A in-memory reliable byte stream

类似于实现一个管道,完成一个类的给定接口实现功能。

  • 字节流在input被写入
  • 字节流以相同的顺序在output被读
  • 字节流是有限的,writer可以结束input,声明自己已写完了所有的数据;
  • reader读完字节流将不再读
  • 字节流的容量是有限的,容器满后writer不能在写入,直到数据被reader读出

实现

  1. 使用双向队列deque作为byte stream的容器:方便在头部移出数据,并且可以拷贝头部若干数据,queue无法实现第二点
  2. 添加两个成员变量:字节流的缓冲区和容量
  3. 阅读接口:需要添加两个成员变量记录已写和已读的字节数
    //! Total number of bytes written
    size_t bytes_written() const;

    //! Total number of bytes popped
    size_t bytes_read() const;
  1. 阅读接口:需要添加一个成员变量,标记是否字节流已写结束
    //! Signal that the byte stream has reached its ending
    void end_input();
  1. end_input的意思是整个stream bytes流结束了,eof的意思是,当writer写完了所有数据,并且reader读完了所有数据后返回1.
// byte_stream.hh

#ifndef SPONGE_LIBSPONGE_BYTE_STREAM_HH
#define SPONGE_LIBSPONGE_BYTE_STREAM_HH

#include 
#include 

class ByteStream {
  private:
    std::deque _buffer{};   // 字节流缓冲
    size_t _capacity = 0;         // 缓冲容量,以字节为单位
    size_t _written_bytes = 0;    // 已写字节数
    size_t _read_bytes = 0;       // 已读字节数
    bool _endinput = false;       // 字节流是否已写结束

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

  public:
  ...
};

#endif  // SPONGE_LIBSPONGE_BYTE_STREAM_HH
// byte_stream.cc

#include "byte_stream.hh"
using namespace std;

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

size_t ByteStream::write(const string &data) {
    size_t written_size = 0;
  
    for(size_t i = 0; i < data.size(); i++) {
        if(remaining_capacity()) {
            _buffer.push_back(data[i]);
            written_size++;
        } else break;
    } 
    _written_bytes += written_size;
    return written_size;
}

string ByteStream::peek_output(const size_t len) const {
    string str = "";
    size_t read_size = len>buffer_size()? buffer_size() : len;
    for(size_t i = 0; i < read_size; i++){
        str += _buffer[i];
    }
    return str;
}

void ByteStream::pop_output(const size_t len) { 
    for(size_t i = 0; i < len && buffer_size(); i++){
        _buffer.pop_front();
        _read_bytes += 1;
    }
}

std::string ByteStream::read(const size_t len) {
    if(eof()) {
        return "";
    } else {
        string read_str = peek_output(len);
        pop_output(len);
        return read_str;
    }
}

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

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

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

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

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

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

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

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

实现一个stream reassembler模块,把字节流中的substrings/segments按照正确顺序放回字节流。

Putting substrings in sequence
  • 整个stream的第一个字节的索引号是0;
  • 默认不会出现不一致的子串;
  • 尽可能早地把字节写进ByteStream;
  • 收到的子串之间可能会有重叠的部分;
  • 不要重复存储子串之间的重叠部分;
  • 字节流索引号
    - read_bytes:Lab0中ByteStream的已读字节数
    - written_bytes:Lab0中ByteStream的已写字节数
应用程序缓冲区ByteStream允许暂存区暂不接收区
0 ~ (read_bytes-1)read_bytes ~ (written_bytes-1)written_bytes ~ (capacity-read_bytes+written_bytes-1)(capacity-read_bytes+written_bytes) ~ eof
Lab2

实现TCPReceiver:思考TCP怎么表示每个字节在字节流中的位置,Receiver负责告诉发送方接收到多少字节(ACK),发送方还能发送多少字节(flow control)。

Lab3

实现TCPSender:当怀疑发送出去的数据丢失在路上了该怎么处理,什么时候该重发一个丢失的segment。

Lab4

整合前面的实验实现TCPConnection。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/656712.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号