实验目的
实现一个TCPreceiver,接收datagram,重排,输出正确顺序的字节流。
要实现的类:StreamReassembler
1 | class StreamReassembler { |
TCPreceiver的容量:字节流中,已经存储在内存中但未被读取的字节流,加上读取了一部分但是还没有接收完毕的字节流,这两部分之和。
不能修改public interface,可以自行添加private interface。
实验思路(踩坑记录)
- 参考手册中给出的图,设置了3个变量:firstUnread, firstUnassembled, firstUnacceptable。
- firstUnread到firstUnacceptable中间的部分是buffer,其大小不超过capacity,用一整个std::string实现。
- 关键的函数是push_substring,大致采用如下的流程:
1 | void push_substring(data, index, eof) { // 注意data可能有重复 |
- 处理EOF必须用“已经写入output的字节数”和“当前EOF下的最后一个字节index”比较!如果当前输入eof为真,则需要更新indexEOF,并且与已经写入的字节数比较。使用其他方式获取真实EOF都有可能漏掉字节。
- buffer必须用“循环”的方式实现。如果不循环,就需要在buffer内部移动字符,这样可能造成输出字符串与输入字符串不一致。尽量不要在buffer内部移动字符。
- 用一个采用了deque实现的bitMap指示当前buffer内部有哪些字节是已经写入的,哪些字节还没有写入。这样做是因为可能第一个字节是最后到达的,因此必须记录哪些字节已到达,哪些未到达。
- unassembled_bytes()用一个单独的变量记录,不要尝试根据bitMap计算,容易出错。
代码
下面列出类StreamReassembler的私有变量。注意涉及指针的用智能指针。
1 | ByteStream _output; //!< The reassembled in-order byte stream |
下面给出该类的方法的实现。
1 | StreamReassembler::StreamReassembler(const size_t capacity) |
通过了
1 | [100%] Testing the stream reassembler... |
总结
这个lab是CS144的正经的第一个lab。整体思路没有太大问题,但是细节上有很多需要注意的地方,需要考虑很多特殊的case。buffer需要用循环的这一点确实没有想到,可能是对buffer内部的修改比较容易出错。