CS144实验笔记

CSS144实验笔记

主要根据这位大佬的笔记和B站的教程进行实验;

lab0

介绍字节流的构造,copy大佬代码,熟悉为主,使用了deque数据结构作为Buffer,实现了write,read等功能,同时设置了一些标志位判断是否Input_end;

lab1

设计了StreamReassembler,体现了TCP传输的特点,接收的字节流可能会乱序到达,因此先通过一个set集合装载带有index的substring作为数据单元(同时带有标志位判断是否是eof结束位),同时设计一个input字节流(lab0中的设计)读取传来的数据,性能上要求尽可能高效地将排好的字节流push走避免在这个assembler中停留过长,同时对后来已经在整理好数据的index之前的数据直接丢弃。set的算法设计比较复杂,直接copy博客大佬代码,bingo~

lab2

先写一个wrap()函数来根据ISN和绝对序列号n转换seqno(精度限制,且可循环),根据文档提示如下图:
wrap_trans

想到的wrap函数实现:先n%232,再加上ISN再%232即得到32位以内的seqno,和博客思路一致,他的写法非常简洁;unwrap函数也不是很难,想到的思路:seqno的值n不断地加WrappingInt32直到接近checkpoint的位置,加了k次WrappingInt32,则absolute sqn=n+k*WrappingInt32-SYN,博客写法思路一致,C++风格很明显;

TCP receiver的实现

TCP recevier的工作原理:(1)从外界获得segments (2)然后用StreamReassembler重整字节流 (3) 计算应答响应信号和窗口大小,这两个数值最后会传输到发送segment中;如图所示,非灰色部分就是本次实验相关的TCP部分;
TCP
接下来即实现segment的工作过程,如图:
TCP segment
主要实现segment_received()
通过syn_flag,base_flag等标志为判断能否继续接收segment,接收segment之后更改SYN标志位,直到接收到带有FIN为true的segment,表明接收完毕;
以及实现 ackno() 表示接收窗口的左边界,如果ISN还未set,返回empty option.
大佬就是大佬代码逻辑清晰易懂,再次感谢,自己写是不可能写出来的;

lab3

lab1和lab2的StreamReassembler和TCPReceiver实现的是将segments carried in unreliable datagrams转变成an incoming byte stream.这次实验的目的是做TCPSender,其作用是将translates from an outgoing byte stream to segments that will become the payloads of unreliable datagrams.
TCPSender写的东西比较多,比如和Receiver相关的序列号,SYN标志位,FLAG标志位等,但从Receiver读到的只有ackno应答信号和window_size两个变量,TCPSender应该实现:

  • keep track到来的window
  • 尽可能地填满窗口直到window is full或者ByteStream为空
  • keep track哪些segments已经发出但还没被receiver确认收到
  • 超时重传

TCPSender如何知道一个segment是否丢失
设定一个(retransmission timeout,RTO)重传超时计时器,一旦超时,自动重传请求(ARQ).每次一个segment发出时,如果这个timer没有运行则将它启动,到一个指定时间段后如果未收到确认则重传(还有一些技术细节,比如记录连续重传次数,double RTO的时间等),当receiver发送给sender新数据的响应序列号之后,还要作RTO时间重新初始化,连续重传次数置零等.

直接copy大佬代码自己写肯定是写不出来的,大佬的代码逻辑真的清晰;
主要写的如下几个函数:
fill_window():把字节流打包成segment发送出去,先置标志位SYN,中间有一段非常重要的while循环:

while((remain = win -(next_seqno - recv_ackno))!=0 && !_fin_flag){
	size_t size = min(TCPConfig::MAX_PAYLOAD_SIZE, remain);
    TCPSegment seg;
    string str = _stream.read(size);
    seg.payload() = Buffer(std::move(str));
    // add FIN
    if (seg.length_in_sequence_space() < win && _stream.eof()) {
    	seg.header().fin = true;
        _fin_flag = true;
     }
     // stream is empty
     if (seg.length_in_sequence_space() == 0) {
     	return;
     }
     send_segment(seg);
}

只要窗口长度大于待确认的序列长度就还能继续传输字节流;
ack_received():(参数:ackno,window_size)
设计了一个_segments_outstanding队列,每发送字节就push进去,再根据ackno将已经确认的字节pop出去;
tick():重传计时器设计
超时之后就把_segments_outstanding中最早的segment重传,重传间隔乘2,重传次数+1,如果没有待重传的segment,重传次数置零;
自定义send_segment(&seg):
置seg.header().seqno位,改_next_seqno位,把seg push到待重传队列中;

lab4

封装TCPReceiver和TCPSender;首先清楚TCPConnection双方都会收发数据;其次难点在于TCP连接的关闭.

为什么要只要三次握手,却要四次挥手
这是因为服务端的LISTEN状态下的SOCKET当收到SYN报文的建连请求后,它可以把ACK和SYN(ACK起应答作用,而SYN起同步作用)放在一个报文里来发送。但关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你未必会马上会关闭SOCKET,即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。

主要根据tcp_state.cc文件中的状态,结合TCP有限状态机的相关知识,在tcp_connection.cc中实现各个状态之间的转换:
FSM
直接copy大佬代码完成tcp_connection.cc文件中的一些函数,大致能看懂逻辑;
最后check_lab4的时候报了一个用户权限错误,一直没解决,在群里问了一下大家都这样就不管了,刚好云主机最后几天也到期了.就暂告一段落.

lab5

这个实验说是做一个网络接口的封装.先了解一下ARP(Address Resolution Protocol)协议——地址解析协议:
教书匠
先拿湖科大教书匠的ppt概括一下MAC地址、IP地址和ARP协议几个概念.

MAC地址和IP地址区别:
MAC位于数据链路层(四层体系中的网络接口层),标记以太网的MAC子层的使用地址;
IP地址是位于网际层使用的地址;
在数据包转发过程中源IP地址和目的IP地址保持不变,源MAC地址和目的MAC地址逐个链路(或逐个网络)改变.

大致理解就是MAC地址和IP地址并非永久绑定的,端口的转发通过ARP协议查询下一个端口的MAC地址.
主要任务是完成network_interface.cc中的几个功能实现IP地址到MAC地址的映射.
send_datagram:用来将IP数据包发送到下一个hop:如果目标MAC地址已知,立即发送;如果目标MAC地址未知,广播一个ARP请求;
recv_frame:判断接收对象——如果内部是IPv4帧,则说明接收的是个数据块;如果内部是ARP,说明接收的是个ARP请求:此时作判断是否与自己的IP地址匹配,根据匹配结果返回一个ARP.
还有个tick() 方法略去不表.

lab6

做的一个IP路由,实现一个Router类:

  • 追踪路由表
  • 正确处理接收的数据帧;

路由表中存储网络前缀和下一跳地址,前缀越长,其他地址块越小,路由越具体,匹配越准确.
写了例如前缀匹配判断,数据进入路由表的条件跳转方法,etc.
大致看了一下代码,就此结束.

总体感觉这个实验加深了我对TCP传输过程的理解,虽然做的很草率~但多少学到点东西,与诸位共勉!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值