CS144 Lab4 : 组装模块
整体设计
TCP FSM
接收数据:
- 如果接收到了带有
RST
标志的段,就要立即进行unclean_shutdown
- 如果接收到的段没有
RST
标志,将有TCPReceiver
来处理这个段的SYN
,payload
,FIN
和seqno
。 - 若果这个段的
seqno
是无效的,或者TCPReceiver
接收这个段失败时,要发送一个空的段给对方
发送数据:
TCPSender
将段发送到自己的队列时,TCPConnection
就要从TCPSender
中取出来放到自己的队列中,在这个过程中如果TCPReceiver
的ackno
为有效值的话,就要给这些段加上ACK
标记,自己的ackno
以及window size
。TCPConnection
通过tick
函数获得时间,我们要将时间交给TCPSender
的tick
函数,让它来进行重传操作。- 重传的次数超过
TCPConfig::MAX_RETX_ATTMPTS
的话就要发送一个RST
的段。 - 如果
TCPConnection
的active
为真,这时TCPConnection
析构了,就要立即发送一个RST
段。
**unclean_shutdown
**:
- 收到
RST
标志的段,就是unclear_shutdown
.
**clean_shutdown
**:
完成 4 次挥手。
先收到
FIN
的一方,在最后发送完不需要进行等待。先发送
FIN
的一方,最后发送ACK
后需要等待一定时间。先收到
FIN
的一方,在收到对方对自己 发送的FIN
的确认ACK
后,就立刻关闭了,不在发送其他数据。先发送
FIN
的一方通过等待 10 $\times$ 初始超时时间限制 时间来确认对方收到了自己的ACK
, 在这段时间里没有重传就结束。
感觉代码有些难写,多次测试不能完全保证每次测试都通过。
TCP 有限状态机
Receiver
Sender
性能优化
使用 gprof
工具分析性能。
可以看到 ByteStream::write
, ByteStream::peek_output
和 ByteStream::pop_output
占用了快 90% 的时间,这主要是方法内部实现使用的深拷贝。
实验在 util
提供了 Buffer
, BufferList
和 BufferListView
这样的类。
Buffer
的 remove_prefix
方法是常数级别的删除前 n
个字符。Buffer
存放的是智能指针,及 size_t
类型的标记来表示字符的开始位置,删除前 n
个字符只需要变动这个标记即可,智能指针指向的内存会随着 Buffer
的析构而释放,在获得性能的同时保持安全。
使用 BufferList
重写 ByteStream
后的性能分析。