Stanford CS144 lab4

  • 总览

    • 一个TCP endpoint(TCPConnection)是TCPSender与TCPReceiver的结合体
    • TCPConnection的segment可以被放入UDP的数据包中或则IP的数据包中
    • 这个lab最后会基于实现的TCPConnection,给出一个叫做CS144TCPSCocket类,并基于此修改之前写的webget
  • TCPConnection的接收发送策略

    • 接受方
      • 如果接受到的报文RST置位,此时需要切断连接,把出入端(in/outbound)设置到错误状态
      • TCPReceiver检查收到的报文段这些字段:seqno,SYN, payload,FIN
      • 如果接受到的报文中ACK置位(一般建立连接后,都是启用状态),那么接受方需要查看acknowindow_size字段
      • 如果传来的报文占据了序列号,那么TCPConnection需要确保至少有一个回应报文,并且其中设置好了正确的acknowindow size
      • 这一段表示需要用到之前的写好的send_empty_segment()
    • 发送方
      • 对于发送出(outgoing)的报文,需要设置好相关字段
      • 发送报文时,一并发送确认,设置好acknowindow_size,并置位ACK,这应该是捎带确认(piggybacking)
    • 时间处理
      • TCPConnection需要告诉调用tick函数的TCPSender距离上一次调用经过的时间
      • consecutive retransmissions超过一个阈值TCPConfig::MAX RETX ATTEMPTS,终止连接,发送一个置位RST报文
  • TCP connection的结束, 涉及到一致性问题

    • 有两种连接结束的方式,第一种是unclean shutdown,也就发送或者接受置位了RST的报文,这种情况下in/outboundByteStream都应该被置为error状态,且active()立即返回false
    • 第二种是clean shutdown,由于两军问题Two Generals Problem, TCP并不能完全实现一个clean shudown
      • 对于一个clean shutdown有四个先置条件,1inbound字节流完全被push并被重组,2outbound字节流被完全出去了,也就是说fin包被发送出去了,3outbound字节已经被遥远的对等实体完全确认了,4本地的对等实体自信的认为遥远的对等实体满足条件3
      • 另外关闭时有两种情况,一种是主动关闭,一种时被动关闭,当然这里的关闭close是对于一端来说的,关闭后自己就可以不发数据了,主动关闭,需要lingering 2MSL(lab里是10 × cfg.rt timeout),,而被动关闭不需要,这里作为附加题,我认为是由于对方先把FIN包发送给过来了,并且作为被动关闭者只要接收到了对方的对于自己的FIN包的ack就能确保关闭但是这段话意味着什么,应该是指对方过早的发送完字节流并且完全被上方应用接受了,那么就完全不需要对方的重传了,这时候就不需要lingering,但是这能够确保对方收到了己方对于对方FIN的ack吗?
  • 实现

    • 对于segment_received函数,
      • 涉及到_sender的ack确认与窗口的修改,也就输是TCPSender::ack_received,修改完对方窗口的大小,_sender需要相应的发送数据;
      • 另外还需要_receiver把数据上传到inbound stream,也就是调用TCPReceiver::segment_received
  • 实现中遇到的问题

    • 面向测试编程,由于测试用例过多(162个),把输出重定向到lab4.log

    • 对于置位RST报文的发送,如果_sender中_segement_out容量为空,那么需要添加一个empty segment

    • kills the connection permanently是指发送rst

    • 这个测试用例是双方同时打开,也就是双方都作为主动发起方,并且这里与《TCP/IP 详解》中描述的不一致,这中情况下,对于第二次握手可以不需要置位SYN了

    • 关于如何测试单个用例

    • 注意需要删除打印语句

    • 吞吐量测试没过,开始排查 lab1中用了unorered_map,太慢,很多人都用set对于std::__detail::_Map_base,减少map索引查找的时间,unordered_map由于是链表存储,最坏的取可以到达O(n)

    • 使用scp命令将本地wsl2项目传递到云服务器上

    • 在ubutun上无法用自己的TCP/IP实现通信,

    • 好吧┭┮﹏┭┮没办法,lab1 stream_reassembler只能够用set重写了

    • 另外更好的优化是在lab0中用BufferList来当作ByteStream的容器,把 ByteStream 类中字节流的容器由 Lab0 最初的 std::list _stream{}; 改为 BufferList _stream{},具体的优化profile,参见这里

    • 几张比较有用的图

    • TCP双方出现同时结束,与同时开启

posted @   抿了抿嘴丶  阅读(449)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示