绊倒可靠的 UDP 实现
Stumbling on a Reliable UDP implementation
我收到了学院的一项任务,我必须通过 UDP aka 实施可靠的传输。 TCP Over UDP(我知道,重新发明轮子,因为这已经在 TCP 上实现了)以深入了解 TCP 的工作原理。一些要求是:3 次握手、拥塞控制(尤其是 TCP Tahoe)和挥手。我考虑用 Java 或 Python.
来做这件事
一些更具体的要求是:
收到每个ACK后:
- (慢启动)如果
CWND < SS-THRESH: CWND += 512
- (拥塞避免)
If CWND >= SS-THRESH: CWND += (512 * 512) / CWND
- 超时后,设置
SS-THRESH -> CWND / 2
、CWND -> 512
,在最后一个确认字节后重传数据。
我找不到有关 TCP Tahoe 实施的更多具体信息。但是据我了解,TCP Tahoe是基于Go-Back-N的,所以我找到了以下发送方和接收方的伪算法:
我的问题是慢启动和拥塞避免阶段应该在 if sendbase == nextseqnum
之后立即发生吗?也就是说,在确认收到预期的 ACK 之后?
我的另一个问题是关于 Window 大小,Go-Back-N 使用固定的 window 而 TCP Tahoe 使用动态的 window。如何根据 cwnd 计算 window 大小?
注意:您的图片无法读取,请提供分辨率更高的图片
我认为该算法不正确。计时器应与每个数据包相关联,并在收到此数据包的 ACK 时停止。当任何数据包的计时器触发时,都会触发拥塞控制。
TCP 不完全是 Go-Back-N 接收器。在 TCP 接收器中也有一个缓冲区。这不需要在发送方 Go-Back-N 处进行任何更改。然而,TCP 也应该实现流量控制,其中接收方告诉发送方其缓冲区中剩余多少 space,并且发送方相应地调整其 window。
注意,Go-Back-N 序列号计算数据包,TCP 序列号计算数据包中的字节,您必须相应地更改算法。
我建议您稍微熟悉一下 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)
。
我收到了学院的一项任务,我必须通过 UDP aka 实施可靠的传输。 TCP Over UDP(我知道,重新发明轮子,因为这已经在 TCP 上实现了)以深入了解 TCP 的工作原理。一些要求是:3 次握手、拥塞控制(尤其是 TCP Tahoe)和挥手。我考虑用 Java 或 Python.
来做这件事一些更具体的要求是:
收到每个ACK后:
- (慢启动)如果
CWND < SS-THRESH: CWND += 512
- (拥塞避免)
If CWND >= SS-THRESH: CWND += (512 * 512) / CWND
- 超时后,设置
SS-THRESH -> CWND / 2
、CWND -> 512
,在最后一个确认字节后重传数据。
我找不到有关 TCP Tahoe 实施的更多具体信息。但是据我了解,TCP Tahoe是基于Go-Back-N的,所以我找到了以下发送方和接收方的伪算法:
我的问题是慢启动和拥塞避免阶段应该在 if sendbase == nextseqnum
之后立即发生吗?也就是说,在确认收到预期的 ACK 之后?
我的另一个问题是关于 Window 大小,Go-Back-N 使用固定的 window 而 TCP Tahoe 使用动态的 window。如何根据 cwnd 计算 window 大小?
注意:您的图片无法读取,请提供分辨率更高的图片
我认为该算法不正确。计时器应与每个数据包相关联,并在收到此数据包的 ACK 时停止。当任何数据包的计时器触发时,都会触发拥塞控制。
TCP 不完全是 Go-Back-N 接收器。在 TCP 接收器中也有一个缓冲区。这不需要在发送方 Go-Back-N 处进行任何更改。然而,TCP 也应该实现流量控制,其中接收方告诉发送方其缓冲区中剩余多少 space,并且发送方相应地调整其 window。
注意,Go-Back-N 序列号计算数据包,TCP 序列号计算数据包中的字节,您必须相应地更改算法。
我建议您稍微熟悉一下 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)
。