CS144 Lab4
这里回顾CS 144 Lab 4: the summit (TCP in full),这次的实验对我难度还是太大了,只能通过85%左右的测试,所以这里只给出一点实验经验。
实验资料:
- https://www.cnblogs.com/kangyupl/p/stanford_cs144_labs.html
- https://kangyupl.gitee.io/cs144.github.io/
- https://gitee.com/kangyupl/sponge
- https://segmentfault.com/a/1190000039220243
- https://kiprey.github.io/2021/11/cs144-lab4/#%E5%85%AD%E3%80%81%E5%85%B7%E4%BD%93%E5%AE%9E%E7%8E%B0
- https://www.cnblogs.com/kangyupl/p/stanford_cs144_labs.html
- http://yuzijun.life/2021-02/CS144
Lab 4: the summit (TCP in full)
准备工作
下载代码以及跑通流程
git checkout -b lab4-startercode
git fetch
git merge origin/lab4-startercode
cd build
make -j4 && make check_lab4
说明
比较重要的3张图:
出处:
- https://cs144.github.io/assignments/lab2.pdf
- https://cs144.github.io/assignments/lab3.pdf
- https://en.wikipedia.org/wiki/File:Tcp_state_diagram_fixed.svg
这里比较重要的就是建立receiver, sender和TCP状态的对应关系,这部分在tcp_state.hh和tcp_state.cc中:
namespace TCPReceiverStateSummary {
const std::string ERROR = "error (connection was reset)";
const std::string LISTEN = "waiting for stream to begin (listening for SYN)";
const std::string SYN_RECV = "stream started";
const std::string FIN_RECV = "stream finished";
} // namespace TCPReceiverStateSummary
namespace TCPSenderStateSummary {
const std::string ERROR = "error (connection was reset)";
const std::string CLOSED = "waiting for stream to begin (no SYN sent)";
const std::string SYN_SENT = "stream started but nothing acknowledged";
const std::string SYN_ACKED = "stream ongoing";
const std::string FIN_SENT = "stream finished (FIN sent) but not fully acknowledged";
const std::string FIN_ACKED = "stream finished and fully acknowledged";
} // namespace TCPSenderStateSummary
TCPState::TCPState(const TCPState::State state) {
switch (state) {
case TCPState::State::LISTEN:
_receiver = TCPReceiverStateSummary::LISTEN;
_sender = TCPSenderStateSummary::CLOSED;
break;
case TCPState::State::SYN_RCVD:
_receiver = TCPReceiverStateSummary::SYN_RECV;
_sender = TCPSenderStateSummary::SYN_SENT;
break;
case TCPState::State::SYN_SENT:
_receiver = TCPReceiverStateSummary::LISTEN;
_sender = TCPSenderStateSummary::SYN_SENT;
break;
case TCPState::State::ESTABLISHED:
_receiver = TCPReceiverStateSummary::SYN_RECV;
_sender = TCPSenderStateSummary::SYN_ACKED;
break;
case TCPState::State::CLOSE_WAIT:
_receiver = TCPReceiverStateSummary::FIN_RECV;
_sender = TCPSenderStateSummary::SYN_ACKED;
_linger_after_streams_finish = false;
break;
case TCPState::State::LAST_ACK:
_receiver = TCPReceiverStateSummary::FIN_RECV;
_sender = TCPSenderStateSummary::FIN_SENT;
_linger_after_streams_finish = false;
break;
case TCPState::State::CLOSING:
_receiver = TCPReceiverStateSummary::FIN_RECV;
_sender = TCPSenderStateSummary::FIN_SENT;
break;
case TCPState::State::FIN_WAIT_1:
_receiver = TCPReceiverStateSummary::SYN_RECV;
_sender = TCPSenderStateSummary::FIN_SENT;
break;
case TCPState::State::FIN_WAIT_2:
_receiver = TCPReceiverStateSummary::SYN_RECV;
_sender = TCPSenderStateSummary::FIN_ACKED;
break;
case TCPState::State::TIME_WAIT:
_receiver = TCPReceiverStateSummary::FIN_RECV;
_sender = TCPSenderStateSummary::FIN_ACKED;
break;
case TCPState::State::RESET:
_receiver = TCPReceiverStateSummary::ERROR;
_sender = TCPSenderStateSummary::ERROR;
_linger_after_streams_finish = false;
_active = false;
break;
case TCPState::State::CLOSED:
_receiver = TCPReceiverStateSummary::FIN_RECV;
_sender = TCPSenderStateSummary::FIN_ACKED;
_linger_after_streams_finish = false;
_active = false;
break;
}
}
最严谨的思路应该是根据不同的TCPState做出不同的动作,但是这部分一直没有调通,只能通过单元测试,无法通过实际的测试,希望之后有机会可以完成这部分。
一些坑
- 这部分实验很依赖于前两次的实验实现,许多问题在前两次中无法体现,导致这次实验很困难;
- 网友表示webget在wsl中似乎无法跑通;
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Doraemonzzz!
评论
ValineLivere