type
status
date
slug
summary
tags
category
icon
password

任务目标:receiver

In Checkpoint 2, you will implement the TCPReceiver, the part of a TCP implementation that handles the incoming byte stream.
The TCPReceiver receives messages from the peer’s sender (via the receive() method) and turns them into calls to a Reassembler(将它们转换为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:
  1. 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.
  1. the available capacity in the output ByteStream. This is called the “window size”.
ackno和window size限定了sender应该发送的数据范围,使用window size,receiver可以控制传输过来的数据的流量,使得sender限制自己传输的字节数,直到receiver可以接收更多数据
We sometimes refer to the ackno as the “left edge” of the window (smallest index the TCPReceiver is interested in), and the ackno + window size as the “right edge” (just beyond the largest index the TCPReceiver is interested in).
This week, you’ll implement the “receiver” part of TCP, responsible for receiving messages from the sender, reassembling the byte stream (including its ending, when that occurs), and determining that messages that should be sent back to the sender for acknowledgment and flow control.
🌊
acknowledgment means, “What’s the index of the next byte that the receiver needs so it can reassemble more of the ByteStream?” This tells the sender what bytes it needs to send or resend. Flow control means, “What range of indices is the receiver interested and willing to receive?” (a function of its available capacity). This tells the sender how much it’s allowed to send.

Translating between 64-bit indexes and 32-bit seqnos

关于seqno、absolute seqno、stream index

在lab1中,每个substring的index都是一个uint64_t,有64位,然而在实际的TCP header里面,sequence number(seqno)应该只有32位,因此应该注意以下三个要点:
  1. Your implementation needs to plan for 32-bit integers to wrap around.
    1. TCP里传输的stream可以无限长,但是index最多32位,也就是说最大的index是,当某个byte的index是时,它的下一个byte的index应该是0
  1. TCP sequence numbers start at a random value
    1. 为了避免与以前的从相同端点开始的连接混淆,seqno不从0开始,而是从一个随机的32位数开始,这个数叫Initial Sequence Number (ISN) The rest of the sequence numbers behave normally after that: the first byte of data will have the sequence number of the ISN+1 (mod ), the second byte will have the ISN+2 (mod ), etc.
  1. The logical beginning and ending each occupy one sequence number
    1. 为确保stream的开头和结尾被可靠地接收到,the SYN (beginning-of stream) and FIN (end-of-stream) control flags are assigned sequence numbers. Keep in mind that SYN and FIN aren’t part of the stream itself and aren’t “bytes”—they represent the beginning and ending of the byte stream itself.
It’s also sometimes helpful to talk about the concept of an “absolute sequence number” (which always starts at zero and doesn’t wrap), and about a “stream index” (what you’ve already been using with your Reassembler: an index for each byte in the stream, starting at zero).
用一个只有三个字母“cat”的stream来理解:
notion image
notion image

接口和代码

理解一个自定义类型:Wrap32:

a wrapper type:一个type里面包含着另一个type,这是为了防止一些bug,在这个例子里面wrapper type里面是uint32_t
We’ve defined the type for you and provided some helper functions (see wrapping_integers.hh) but you’ll implement the conversions in wrapping_integer.cc:
  1. static Wrap32 wrap( uint64_t n, Wrap32 zero_point );
    1. 将absolute seqno转换为seqno,n为一个absolute seqno,zero_point是initial sequence number,要求返回n对应的seqno
  1. uint64_t unwrap( Wrap32 zero_point, uint64_t checkpoint ) const;
    1. 将seqno转换为absolute seqno,zero_point为initial sequence number,要求返回距checkpoint最近的一个absolute seqno(因为一个seqno可以对应多个absolute seqno,只要mod的结果一样)

代码

.hh没有变化
wrapping_integers.cc

Implementing the TCP receiver

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.

接口和代码

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()方法:
This is method will be called each time a new segment is received from the peer’s sender. This method needs to:
  • 在有需要时设置初始序列号
    • 因为在SenderMessage里面,ISN只不过是一个bool值,没有具体是多少,因此当有一个ISN=true的message传过来时,应该在receiver这里设置ISN以应对wrapper的转换
  • Push any data to the Reassembler.
    • resembler接收从0开始的index,因此把数据传输给resembler时需要把seqno unwrap,并且当FIN=true时,is_last_index = true

代码

tcp_receiver.hh
tcp_receiver.cc
JAVA的语法积累CS144-C++语法积累
  • Giscus