绊倒可靠的 UDP 实现

Stumbling on a Reliable UDP implementation

我收到了学院的一项任务,我必须通过 UDP aka 实施可靠的传输。 TCP Over UDP(我知道,重新发明轮子,因为这已经在 TCP 上实现了)以深入了解 TCP 的工作原理。一些要求是:3 次握手、拥塞控制(尤其是 TCP Tahoe)和挥手。我考虑用 Java 或 Python.

来做这件事

一些更具体的要求是:

收到每个ACK后:

我找不到有关 TCP Tahoe 实施的更多具体信息。但是据我了解,TCP Tahoe是基于Go-Back-N的,所以我找到了以下发送方和接收方的伪算法:

我的问题是慢启动和拥塞避免阶段应该在 if sendbase == nextseqnum 之后立即发生吗?也就是说,在确认收到预期的 ACK 之后?

我的另一个问题是关于 Window 大小,Go-Back-N 使用固定的 window 而 TCP Tahoe 使用动态的 window。如何根据 cwnd 计算 window 大小?

注意:您的图片无法读取,请提供分辨率更高的图片

  1. 我认为该算法不正确。计时器应与每个数据包相关联,并在收到此数据包的 ACK 时停止。当任何数据包的计时器触发时,都会触发拥塞控制。

  2. TCP 不完全是 Go-Back-N 接收器。在 TCP 接收器中也有一个缓冲区。这不需要在发送方 Go-Back-N 处进行任何更改。然而,TCP 也应该实现流量控制,其中接收方告诉发送方其缓冲区中剩余多少 space,并且发送方相应地调整其 window。

  3. 注意,Go-Back-N 序列号计算数据包,TCP 序列号计算数据包中的字节,您必须相应地更改算法。

  4. 我建议您稍微熟悉一下 rfc793。它没有拥塞控制,但它指定了其他 TCP 机制应该如何工作。 this link 也很好地说明了 TCP window 以及与之相关的所有变量。

My question is the Slow Start and Congestion Avoidance phase should happen right after if sendbase == nextseqnum? That is, right after confirming the receipt of an expected ACK?

你的算法只有在收到最后一个数据包的 ACK 时才会做一些事情。正如我所说,这是不正确的。

无论如何。每个确认新数据包的 ACK 都应该触发 window 增加。您可以通过检查 send_base 是否因 ACK 而增加来进行检查。

不知道是否每个 Tahoe 实现都这样做,但您可能也需要它。在三个连续的重复 ACK 之后,即不增加 send_base 的 ACK 触发拥塞响应。

My other question is about the Window Size, Go-Back-N uses a fixed window whereas TCP Tahoe uses a dynamic window. How can I calculate window size based on cwnd?

您将 N 设为变量而不是常量,并将拥塞 window 分配给它。

在具有流量控制的真实 TCP 中,您可以执行 N = min (cwnd, receiver_window)