type
status
slug
date
summary
tags
category
password
icon
task0:Wrapper
看看接口要求:
we’ll represent sequence numbers with a custom type: Wrap32, and write the conversions between it and absolute sequence numbers (represented with uint64 t). Wrap32 is an example of a wrapper type: a type that contains an inner type (in this case uint32 t) but provides a different set of functions/operators.
Hint #2: We’re expecting one line of code for wrap, and less than 10 lines of code for unwrap. If you find yourself implementing a lot more than this, it might be wise to step back and try to think of a different strategy
乐,极限压行到只有5行unwrap
wrap就只需要把输入的zero_point里面原始数据拉成64位和absolute做加法就可以了,结果对32位二进制最大数取模。不过由于c++的特性(这点主要是无符号的类型转换的理解)可以写的比较简洁:
然而unwrap就会复杂一些,因为要根据checkpoint来选取合适的absolute seqno:
A checkpoint is required because any given seqno corresponds to many absolute seqnos. E.g. with an ISN of zero, the seqno “17” corresponds to the absolute seqno of 17, but also + 17, or + 17, or + + 17, or + 17, or + + 17, etc. The checkpoint helps resolve the ambiguity: it’s an absolute seqno that the user of this class knows is “in the ballpark” of the correct answer. In your TCP implementation, you’ll use the first unassembled index as the checkpoint.
之前有个困扰是zero_point有啥用,所以我就去看了测试用例,果然是因为在发烧导致基本的思路都没理清:
这里因为代码量少,限于作者要求,不会贴出代码,不过实在不行可以看我的仓库,按照commit来进行的阶段性进展描述。
task1 Implementing the TCP receiver
In the rest of this lab, you’ll be implementing the TCPReceiver.
It will (1) receive messages from its peer’s sender and reassemble the ByteStream using a Reassembler, and (2) send messages back to the peer’s sender that contain the acknowledgment number (ackno) and window size. We’re expecting this to take about 15 lines of code in total.
First, let’s review the format of a TCP “sender message,” which contains the information about the ByteStream. These messages are sent from a TCPSender to its peer’s TCPReceiver:
The TCPReceiver generates its own messages back to the peer’s TCPSender:
Your TCPReceiver’s job is to receive one of these kinds of messages and send the other:
以上是提要,接下来是对于实现receive()
receive()
This is method will be called each time a new segment is received from the peer’s sender.
This method needs to:
- Set the Initial Sequence Number(ISN) if necessary. The sequence number of the first-arriving segment that has the SYN flag set is the initial sequence number. You’ll want to keep track of that in order to keep converting between 32-bit wrapped seqnos/acknos and their absolute equivalents. (Note that the SYN flag is just one flag in the header. The same message could also carry data or have the FIN flag set.)
- Push any data to the Reassembler. If the FIN flag is set in a TCPSegment’s header, that means that the last byte of the payload is the last byte of the entire stream. Remember that the Reassembler expects stream indexes starting at zero; you will have to unwrap the seqnos to produce these.
Development
- Implement the TCPReceiver’s public interface (and any private methods or functions you’d like) in the file tcp_receiver.cc. You may add any private members you like to the TCPReceiver class in tcp receiver.hh.
再读一遍最开始的overview的细节:
The TCPReceiver receives messages from the peer’s sender (via the receive() method) and turns them into calls to a Reassembler, which eventually writes to the incoming ByteStream. Applications read from this ByteStream, just as you did in Lab 0 by reading from the TCPSocket. Meanwhile, the TCPReceiver also generates messages that go back to the peer’s sender, via the send() method. These “receiver messages” are responsible for telling the sender:
- the index of the “first unassembled” byte, which is called the “acknowledgment number” or “ackno.” This is the first byte that the receiver needs from the sender.
- the available capacity in the output ByteStream. This is called the “window size”
注意之前说过最开始的ISN的选择:
The first sequence number in the stream is a random 32-bit number called the Initial Sequence Number (ISN).
有个难点是不知道怎么更新next_bytes,它是absolute seqno,用作unwrap里面的chekpoint参数,前面提到In your TCP implementation, you’ll use the first unassembled index as the checkpoint.
那我怎么得到这个first unassembled index呢?
只需要一个syn的长度加上bytes_pushed的大小即可
遇到的一些问题:
这个情况就是说末尾来了,但是暂时还不能装进去的时候,你的索引要合适
看着测试写,总的来说比较简单,代码量不大,附上github仓库地址:
- 作者:liamY
- 链接:https://liamy.clovy.top/article/cs144/lab2
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。