首页 > 其他分享 >【计算机网络】Stanford CS144 Lab 2: the TCP receiver 学习记录

【计算机网络】Stanford CS144 Lab 2: the TCP receiver 学习记录

时间:2023-02-04 00:11:34浏览次数:35  
标签:max const Stanford seqno CS144 pos TCP isn res

这次实验的目标为实现一个 TCP协议 的接收器。

Sequence Numbers

Sequence Numbers Absolute Sequence Numbers Stream Indices
Start at the ISN Start at 0 Start at 0
Include SYN/FIN Include SYN/FIN Omit SYN/FIN
32 bits, wrapping 64 bits, non-wrapping 64 bits, non-wrapping
"seqno" "absolute seqno" "stream index"

我们要实现的就是 "seqno" 与 "absolute seqno" 之间的互相转换。

"seqno" => "absolute seqno"

"seqno" 向 "absolute seqno" 的转换可能并不唯一, 因此我们找到离 checkpoint 最近的那一个。

"seqno" 一定是在 \([max(checkpoint - (1 << 31), 0), checkpoint + (1 <<31)]\)

WrappingInt32 wrap(uint64_t n, WrappingInt32 isn) {
    const uint64_t max_seqno = uint64_t{1} << 32;
    if (n < max_seqno - isn.raw_value()) {
        return WrappingInt32{isn + n};
    }
    n -= (max_seqno - isn.raw_value());
    const uint32_t res = n % max_seqno;
    return WrappingInt32{res};
}

uint64_t unwrap(WrappingInt32 n, WrappingInt32 isn, uint64_t checkpoint) {
    // DUMMY_CODE(n, isn, checkpoint);
    const uint64_t max_seqno = uint64_t{1} << 32;
    const int32_t count = (checkpoint < max_seqno ? 0 : checkpoint / max_seqno);
    uint64_t res{0};
    if (n.raw_value() >= isn.raw_value()) {
        res = n.raw_value() - isn.raw_value();
    } else {
        res = max_seqno - isn.raw_value() + n.raw_value();
    }
    res += (max_seqno * count);
    if (res > checkpoint && res >= max_seqno) {
        if (res - checkpoint > max_seqno / 2) res -= max_seqno;
    } else if (res < checkpoint) {
        if (checkpoint - res > max_seqno / 2) res += max_seqno;
    }
    return res;
}

Implementing the TCP receiver

需要注意:

  • 在接收一个 SYN 前,任何数据段都会被拒绝

  • 接收一个 SYN 后,不再接收含有 SYN 的 TCPSegment

  • 接收一个 FIN 后,不再接收含有 FIN 的 TCPSegment

  • TCPSegment 的数据与接收窗口没有交集就会被拒绝

  • SYN 和 FIN 都会占用一个序号

stream_reassembler.hh

class StreamReassembler {
  public:
    size_t head_index() const { return _head_index; }
    bool input_ended() const { return _output.input_ended(); }
    // ...
}

tcp_receiver.hh

class TCPReceiver {
    //! Our data structure for re-assembling bytes.
    StreamReassembler _reassembler;

    //! The maximum number of bytes we'll store.
    size_t _capacity;

    uint64_t _pos{0};
    bool _fin{false};
    std::optional<WrappingInt32> _isn{std::nullopt};
    // ...

tcp_receiver.cc

bool TCPReceiver::segment_received(const TCPSegment &seg) {
    const bool issyn = seg.header().syn;
    const bool isfin = seg.header().fin;
    const bool refuse = (_isn != nullopt && issyn) || (_fin && isfin) || (_isn == nullopt && !issyn);

    if (refuse) return false;
    if (issyn) {
        _isn = seg.header().seqno;
        _pos = 1;
    }

    if (isfin) _fin = true;

    const uint64_t abs_seqno = unwrap(seg.header().seqno, _isn.value(), _pos);
    const uint64_t index = abs_seqno + (issyn ? 1 : 0);

    const bool inbound = abs_seqno + seg.length_in_sequence_space() <= _pos || abs_seqno >= _pos + window_size();

    if (!issyn && !isfin && inbound) 
        return false;
    // SYN 不被算在 “Stream index” 中,因此index - 1。
    _reassembler.push_substring(seg.payload().copy(), index - 1, isfin); 
    _pos = _reassembler.head_pos() + 1;
    // FIN 会占一个序号
    if (_reassembler.input_ended()) {  
        _pos++;
    }

    return true;
}

optional<WrappingInt32> TCPReceiver::ackno() const {
    return _pos == 0 ? std::nullopt : optional<WrappingInt32>{wrap(_pos, _isn.value())};
}

size_t TCPReceiver::window_size() const { return _reassembler.stream_out().remaining_capacity(); }

标签:max,const,Stanford,seqno,CS144,pos,TCP,isn,res
From: https://www.cnblogs.com/mingzi47/p/17090734.html

相关文章

  • 从0写TCPIP协议栈2:开发概述
    开发概述:协议栈框架介绍在正式开发前,先将本次的目标框架介绍下:本次需要在Windows环境下基于C++语言实现一个简单的:Web服务器协议栈框架+客户计算机协议栈框架+网页设计......
  • webrtc RTCPeerConnection前端使用记录
    参考资料​​https://developer.mozilla.org/zh-CN/docs/Web/API/RTCPeerConnection​​​​https://developer.mozilla.org/zh-CN/docs/Web/API/RTCPeerConnection#created......
  • 转载--查看所有tcp连接数
    查看所有tcp连接数 转载地址:https://blog.csdn.net/u010833154/article/details/128012562netstat-n|awk'/^tcp/{++S[$NF]}END{for(ainS)printa,S[a]}'......
  • 【计算机网络】Stanford CS144 Lab1 : stitching substrings into a byte stream 学
    Puttingsubstringsinsequence实现一个流重组器。可以将带有索引的流碎片按照顺序重组。这些流碎片是可以重复的部分,但是不会有冲突的部分。这些流碎片将通过Lab0中......
  • 基于pythondetcp多个客户端连接服务器
    壹:TCP是面向运输层的协议。使用TCP协议之前,必须先建立TCP连接,在传输完成后,必须释放已经建立的TCP连接。每条TCP连接只能有两个端,每一条TCP连接只能是点对点的。TCP提供可......
  • QTcpServer和QTcpSocket使用详解
    QTcpServer和QTcpSocket使用详解1、基本使用方法QTcpServer和QTcpSocket的使用是密不可分的,所以两者一块演示使用方法。QTcpServer常用信号:newConnection()信号,该信号用于处......
  • Python网络编程—TCP客户端和服务器
    Python网络编程—TCP客户端和服务器客户端importsocket'''客户端创建步骤:1、创建网络套接字2、连接到目标IP地址和端口3、收发数据4、关闭套接字'''IP=socket.gethostnam......
  • 利用natapp实现TCP、UDP内网穿透
    利用natapp实现TCP、UDP内网穿透natapp官网:​​https://natapp.cn/​​下载:下载下来其实就只有一个文件:首先在natapp官网上注册一个账号,并实名认证,这一步是必须的!然后去购买......
  • python tcp socket 源码分享
    服务端的源码:importsocketserverclassHandler_TCPServer(socketserver.BaseRequestHandler):"""TheTCPServerclassfordemonstration.Note:We......
  • tcp相关知识
         ......