CS144 Lab Assignments - 手写TCP - LAB4

CS 144: Introduction to Computer Networking, Fall 2020https://cs144.github.io/My Repohttps://github.com/wine99/cs144-20fa思否主页:https://segmentfault.com/u/wine99任务本节实现 TCPConnection 类,实例化这个类将作为一个完整的 TCP 连接中的一个 peer(可以充当任意一方,Server 或 Client)。前面两个实验分.
摘要由CSDN通过智能技术生成

CS 144: Introduction to Computer Networking, Fall 2020
https://cs144.github.io/

My Repo
https://github.com/wine99/cs144-20fa

思否主页:https://segmentfault.com/u/wine99

任务

本节实现 TCPConnection 类,实例化这个类将作为一个完整的 TCP 连接中的一个 peer(可以充当任意一方,Server 或 Client)。前面两个实验分别实现的 TCPSender 和 TCPReceiver 并不能作为一个独立的 Server 或 Client,这两个类的实例是用作 TCPConnection 实例的内部成员,即下图。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oLsaWSnJ-1613613511043)(https://s3.ax1x.com/2021/02/17/ygfFsI.png)]

Sender 和 Receiver 的作用

  • 收到报文段时
    • 通知 _receiver:根据报文段的 seqno、SYN、FIN 和 payload,以及当前状态,更新 ackno;收集数据
    • 通知 _sender:根据报文段的 ackno 以及当前状态,更新 next_seqno;更新 window_size
  • 发送报文段时
    • _sender 负责填充 payload、seqno、SYN、FIN,注意有可能既没有 payload 也没有 S、F 标识(empty segment),这和 Lab3 实现的 _sender 的 ack_received() 逻辑不同
    • _receiver 负责填充 ackno、window size

FSM

结合 Lab2、Lab3 讲义中的 TCPSender 和 TCPReceiver 的状态转换图,tcp_state.cc 中 TCPConnection 的各状态与 sender、receiver 状态的对应关系,以及下面的 TCPConnection 的状态转换图,理解整个 TCP 连接。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6nkTWJgd-1613613511046)(https://s3.ax1x.com/2021/02/17/yg5iQJ.jpg)]

Edge case

在实现过程中,需要额外关注收到报文段时 TCPSender 和 TCPConnection 的逻辑的不同之处。这些细节来源于

  1. Lab2 中的 receiver 只关心收到数据和数据有关的标识;Lab3 中 sender 只关心收到的 ackno 和 win,不处理也不知道收到的数据和其他信息,在 _stream_in() 没有数据时可能不会做任何动作(我的 Lab3 实现是这样的),而在 Lab4 中可能还需要发一个空的 ACK 报文段
  2. 连接建立和释放过程中的各种特殊情况
    1. 发完 SYN 后马上收到 RST
    2. 发完 SYN 后马上收到 FIN
    3. Simultaneous open
    4. Simultaneous shutdown

实验给出的测试套非常完备,覆盖了各种特殊情况,Simultaneous open 和 Simultaneous shutdown 的情况见下图。按照讲义所说,如果你的 Lab2 和 Lab3 实现非常 robust,Lab4 的大部分工作是 wire up 前面两个类的接口,但也有可能你需要修改前两个实验的实现。

下图出处:TCP State Transitions

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cGUvyySG-1613613511048)(https://s3.ax1x.com/2021/02/17/yg7ih6.jpg)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bvKSD7pC-1613613511050)(https://s3.ax1x.com/2021/02/17/yg7A1O.jpg)]

实现

我的实验四的函数框架参考了 这篇博客,但实现不同。我在网上浏览过的几个实现,均改动了 Lab2、Lab3 的函数签名,让 Lab2、Lab3 的实现变得不太干净。我的最终实现没有入侵 Lab3 和 Lab2 的代码,细节逻辑全部在 TCPConnection 类中完成。

注意如果 tests 文件夹中的测试全部通过但是 txrx.sh 中的测试不通过,并且不通过的原因是结果的哈希值不同,去掉所有的自己添加的打印语句,再进行测试。

实验四刚开始时一度想要放弃,但最终花费的时间居然比实验三要少(实验三零零碎碎花了六天左右,实验四大概花费了集中的两天半时间)。通过全部测试的时候,还感觉有点懵逼,怎么就通过了,我真的把细节都处理完了?第一次意识到,复杂的项目中,完备的测试比“充满自信”的实现代码可靠多了,也不得不感慨课程质量之高以及讲师和助教付出的心血。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5UNiJ3iX-1613613511052)(https://s3.ax1x.com/2021/02/17/y2kzRO.png)]

代码

添加的成员变量

class TCPConnection {
   
  private:
    size_t _time_since_last_segment_received{
   0};
    bool _active{
   true};

    void send_sender_segments();
    void clean_shutdown();
    void unclean_shutdown();

实现代码

#include "tcp_connection.hh"

#include <iostream>

using namespace std;

size_t TCPConnection::remaining_outbound_capacity() const {
    return _sender.stream_in().remaining_capacity(); }

size_t TCPConnection::bytes_in_flight() const {
    return _sender.bytes_in_flight(); }

size_t TCPConnection::unassembled_bytes() const {
    return _receiver.unassembled_bytes(); }

size_t TCPConnection::time_since_last_segment_received() const {
    return _time_since_last_segment_received; }

bool TCPConnection::active() const {
    return _active; }

void TCPConnection::segment_received(const TCPSegment &seg) {
   
    if (!_active)
        return;
    _time_since_last_segment_received = 0;
    // State: closed
    if (!_receiver.ackno().has_value() && _sender.next_seq
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值