IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> CS144_lab4 -> 正文阅读

[开发测试]CS144_lab4

lab4(未完,待续)


啊,做到lab4,我真的已经快被掏空了,脑子都是一片混乱的,lab的文档有些都看不懂,难度确实太大了(对我来说

最后只能借鉴大佬们的思路了,就摁抄

但还是有些测试用例没通过,不知道是前几个lab的问题还是哪里出错了,哎,累了,过几天有兴趣再搞,pass 掉先

tcp_connection.hh

//! record the time_since_last_segment_received
size_t _time_since_last_segment_received{};
bool _active {true};
//! \brief send the segments from TCPSender's segment_out
void send_sender_segments();
//! \brief brain-bending part, clean shutdown 
void clean_shutdown();
//! \brief brain-bending part, unclean shutdown
void unclean_shutdown();

tcp_connection.cc


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) {
    //判断TCPConnection 的状态
    if(!_active){
        return;
    }

    //计时,最近一次 segment 到达的时间
    _time_since_last_segment_received = 0;

    //State: closed
    //发送来的没值,而且下一个要发的byte的absolute seqo是0
    //说明是要建立连接
    if(!_receiver.ackno().has_value() && _sender.next_seqno_absolute() == 0){
        if(!seg.header().syn){
            return;
        }
        _receiver.segment_received(seg);
        connect();
        return;
    }

    //State: syn sent
    //发过syn了且recvived为空,表明未收到发来的syn
    if(_sender.next_seqno_absolute() > 0 && _sender.bytes_in_flight() == _sender.next_seqno_absolute()
    && !_receiver.ackno().has_value()){
        //收到的payload有值,不管
        if(seg.payload().size()){
            return;
        }
        //如果在 syn-sent 状态下,收到对方的 syn
        if(!seg.header().ack){
            if(seg.header().syn){
                // simultaneous open,切换到 State: sent-received 
                _receiver.segment_received(seg);
                _sender.send_empty_segment();
            }
            return;
        }
        //收到 reset
        if(seg.header().rst){
            _receiver.stream_out().set_error();
            _sender.stream_in().set_error();
            _active = false;
            return;
        }
    }

    //收到的是建立连接之后的数据
    _receiver.segment_received(seg);
    //存下ack number,以及weindow size,为下次发送做准备
    _sender.ack_received(seg.header().ackno,seg.header().win);

    // Lab3 behavior: fill_window() will directly return without sending any segment.
    if(_sender.stream_in().buffer_empty() && seg.length_in_sequence_space()){
        _sender.send_empty_segment();
    }

    //建立连接之后收到 reset
    if(seg.header().rst){
        _sender.send_empty_segment();
        unclean_shutdown();
        return;
    }
    //发数据
    send_sender_segments();
}




size_t TCPConnection::write(const string &data) {
    if(!data.size()){
        return 0;
    }
    size_t written_len = _sender.stream_in().write(data);
    
     _sender.fill_window();
    //发送,其实感觉可以没这个发送
    send_sender_segments();
    
    return written_len;
}

//! \param[in] ms_since_last_tick number of milliseconds since the last call to this method
void TCPConnection::tick(const size_t ms_since_last_tick){ 
    //时间检查,超时重发
    if(!_active){
        return;
    }
    _time_since_last_segment_received += ms_since_last_tick;
    //递归等return
    _sender.tick(ms_since_last_tick);
    //超时重传次数过多
    if(_sender.consecutive_retransmissions() > TCPConfig::MAX_RETX_ATTEMPTS){
        //异常
        unclean_shutdown();
    }
    //发
    send_sender_segments();
  
}

void TCPConnection::end_input_stream() {
    // stop outbound byte stream input
    _sender.stream_in().end_input();

    //发送断开连接的segment
    _sender.fill_window();
    send_sender_segments();
}

void TCPConnection::send_sender_segments(){
    
    TCPSegment seg;
    while(!_sender.segments_out().empty()){
        //获取sender头
        seg = _sender.segments_out().front();
        //更新状态
        _sender.segments_out().pop();
        //根据 receiver 的 ackno 值 设置 segments 的标志位
        if(_receiver.ackno().has_value()){
            seg.header().ack = true;
            seg.header().ackno = _receiver.ackno().value();
            seg.header().win = _receiver.window_size();
        }
        _segments_out.push(seg);
    }
    clean_shutdown();
}

void TCPConnection::connect() {
    //给 Sender 上数据
    _sender.fill_window();
    
    //用 TCPConnection 发出去
    send_sender_segments();

}

TCPConnection::~TCPConnection() {
    try {
        if (active()) {
            cerr << "Warning: Unclean shutdown of TCPConnection\n";
            // Your code here: need to send a RST segment to the peer
            // 当调用析构函数,并且 active() 值为 true 时,需要发送一个空的segments附带 RST FALG
            _sender.send_empty_segment();
            unclean_shutdown();
        }
    } catch (const exception &e) {
        std::cerr << "Exception destructing TCP FSM: " << e.what() << std::endl;
    }
}

void TCPConnection::clean_shutdown(){
    if(_receiver.stream_out().input_ended()){
        if(!_sender.stream_in().eof()){
            _linger_after_streams_finish = false;
        }else if(_sender.bytes_in_flight() == 0){
            if(!_linger_after_streams_finish || time_since_last_segment_received() >= 10 * _cfg.rt_timeout){
                _active = false;
            }
        }
    }
}

void TCPConnection::unclean_shutdown(){
    // When this being called, _sender.stream_out() should not be empty.
    _receiver.stream_out().set_error();
    _sender.stream_in().set_error();
    _active = false;
    TCPSegment seg = _sender.segments_out().front();
    _sender.segments_out().pop();
    seg.header().ack = true;
    if(_receiver.ackno().has_value()){
        seg.header().ackno = _receiver.ackno().value();
    }
    seg.header().win = _receiver.window_size();
    seg.header().rst = true;
    _segments_out.push(seg);
}

  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2021-07-07 00:07:16  更:2021-07-07 00:08:01 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/2 19:21:54-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码