就我个人而言,我什至不认为需要 ACK。如果我们只为丢失的数据包发送 NACK(n) 而不是为每个接收到的数据包发送一个 ACK 会更快。那么何时/哪些情况会使用 ACK 而不是 NACK,反之亦然?
NACK 与 ACK?什么时候用一个而不是另一个?
ACK 的原因是 NACK 是不够的。假设我向您发送 X 段的数据流(为简单起见,假设为 10)。
您的连接状况不佳,并且只接收第 1、2、4 和 5 段。您的计算机发送第 3 段的 NACK,但没有意识到应该有第 6-10 段,并且没有 NACK 那些。
因此,我重新发送了第 3 段,但随后我的计算机错误地认为数据已成功发送。
ACK 提供了该段已经到达目的地的一些保证。
如果您希望应用程序处理数据和重传的顺序,您可以简单地选择使用像 UDP 这样的协议(例如,像 TFTP 那样)。
这一切都归结为丢失概率分布和流量模式。
以典型的无线链路为例,丢失率稳定在 10-30%。如果您确认每个接收到的帧(如 802.11abg),您将快速检测到帧丢失的时间,因此您不会浪费时间等待超时。
如果您改为 NAK,您将变得依赖于流量模式: - 如果您发送单个请求数据包并期望得到答复,并且该请求丢失,则您将不得不超时,如果您没有收到回答。- 如果您只是向大多数静音的接收者发送数据包流,那么仅在接收者接收下一个数据包时才接收 NAK 是可以接受的。但这意味着接收者必须对数据包重新排序,并且发送者必须跟踪它已发送的大量积压消息。
(猜猜 802.11n 选择什么解决方案?两者都有。接收器发送它已接收帧的可变长度位图)
现在以一个典型的 Internet 网络为例:您有接近 0% 的丢包率,直到发生不好的事情,并且在遵循一些指数分布规律的特定时间内,您有接近 100% 的丢包率,从 200 毫秒的中断到一分钟和一分钟一半。
在非有损网络中确认每个数据包似乎毫无意义,除非您考虑链接被切断的情况:您可能在很长一段时间内都不会收到 ACK 或 NACK,并且接收器通常不会发送任何内容,直到链接断开被恢复。
如果使用 ACK,则发送方将停止发送并保留其积压,直到链接恢复。如果您改为使用 NACK,那么接收方最终可能会告诉您,它很久没有收到从发送方积压中掉下来的数据包,并且连接基本上是不可恢复的。
ACK 在滑动窗口协议中很有用,它们允许发送器 A 知道发送的数据已被远程 B 接收。然后发送器 A 可以继续发送下一个数据 - 直到其发送窗口已满(发送到远程但尚未发送的数据)承认)。
ACK 可能被认为比 NAK 更重要。NAKs 只是允许更快的恢复,在 A 发送的数据包/块没有被 B 接收的情况下,B 通过某种方式检测到数据包/块丢失。
设计一个支持可靠传输和流量控制的协议是完全可行的,仅使用 ACK,不使用 NAK(在 Transmitter 没有收到 ACK 的情况下由 Transmitter 重传,任何情况下都需要重传机制)。
我想在这里添加一件最重要的事情,在 TCP 中,我们不会为每个收到的数据包发送 ACK。
但是,仅针对最后接收的数据包发送 ACK。
如果我错了,请纠正我。