通过 UDP 实现 ack?
Posted
技术标签:
【中文标题】通过 UDP 实现 ack?【英文标题】:implementing ack over UDP? 【发布时间】:2010-12-03 15:28:07 【问题描述】:我们有一个通过 UDP 执行通信的系统(用 C 语言构建)。最近我们发现有必要保证数据包的传递。我的问题是:为确保使用 ack 数据包进行传递,基于 UDP 的系统的最少添加是什么?此外,理想情况下无需操作数据包标头。我们对数据包进行应用程序级别的控制,包括序列号和 ack/nack 标志。我想知道这是否是一个失败的原因,我们尝试做的任何事情基本上都是有缺陷和损坏的 TCP 版本。基本上,我们是否可以进行最低限度的改进来实现有保证的交付(我们不需要 TCP 的许多功能,例如拥塞控制等)。谢谢!
【问题讨论】:
你确定值得吗?简单地使用经过验证的技术与自制系统。性能优势是否明确,或者您只是过早地进行优化? 系统是实时的,已经符合需要UDP的规范。 【参考方案1】:TCP 将 3 个可能相关的服务交织在一起(好吧,TCP 做得更多,但我只讨论 3 个。)
-
按订单发货
可靠的交付
流控制
您刚刚说您不需要流量控制,所以我什至不会解决这个问题(您将如何宣传窗口大小等,除了您可能需要一个窗口。我会得到给它。)
您确实说过您需要可靠的交付。这并不难——你使用 ACK 来表明发送者已经收到了一个数据包。基本的可靠交付如下所示:
-
发送方发送数据包
Receiver收到数据包,然后发送ack
如果发送方没有收到确认(通过计时器),他会重新发送数据包。
这三个步骤不能解决这些问题:
-
如果 ACK 丢失怎么办?
如果数据包乱序到达怎么办?
因此,对于您的应用程序,您说您只需要可靠的交付 - 但没有说明需要按顺序执行。这将影响您实现协议的方式。
(顺序无关紧要的示例:您将员工记录从一台计算机复制到另一台计算机。如果 Alice 的记录在 Bob 之前收到,这无关紧要,只要两者都到达那里。)
因此,假设您只需要可靠(因为这就是您在帖子中所说的),您可以通过多种方式实现这一目标。
您的发件人可以跟踪未确认的数据包。所以如果它发送#3、4、5和6,并且没有得到3和4的ACK,那么发送者就知道它需要重传。 (虽然发送方不知道数据包 3 和 4 是否很多,或者它们的 ACK 是否丢失。无论哪种方式,我们都必须重新发送。)
但是您的发送方可以进行累积 ACK - 因此在上面的示例中,如果它收到 3、4 和 5,它只会确认 #6。这意味着接收方将丢弃数据包6 如果之前没有收到过。如果您的网络非常可靠,那么这可能不是一个坏选择。
然而,上述协议确实有一个窗口——即发送方一次发送多少个数据包?这意味着您确实需要某种窗口,但不是出于流量控制的目的。您将如何传输窗口大小?
你可以在没有窗口的情况下做到这一点,方法是让窗口大小保持不变,或者做一些类似停止等待的事情。前者可能是更好的选择。
无论如何,我还没有直接回答你的问题,但我希望我已经指出了一些在构建它时值得考虑的事情。在没有部分流量控制(如窗口)且不考虑有序的情况下进行“可靠传输”的任务非常困难! (让我知道我是否应该提供有关其中一些内容的更多详细信息!)
祝你好运!
【讨论】:
【参考方案2】:看看 Steven 的UNIX Network Programming, volume 1 的第 8 章和第 20 章。他涵盖了许多不同的方法。第 20.5 节“为 UDP 应用程序添加可靠性”可能是您最感兴趣的。
【讨论】:
+1 供参考。以前为编程任务做类似的事情时,那部分很棒。【参考方案3】:我有一个运行 here 的问题,它正在收集“当您需要可靠的 UDP 时使用什么”的答案。答案可能比您想要或需要的要多得多,但您也许可以查看一些基于 UDP 构建的协议,并仅获取您需要的 ACK 部分。
根据我使用 ENet 协议(一种可靠的 UDP 协议)的工作,我希望您在每个 UDP 数据报中都需要一个序列号,这是一种为您收到的数据报发送 ACK 的方法,一种保持您发送的数据报,直到您收到它们的 ACK 或它们超时,以及一种计时重新发送您尚未收到 ACK 的数据报的方法......当您决定时,我还会添加一个整体超时你永远不会传递一个特定的数据报,我猜,一个回调到你的应用层来通知它这个失败的传递......
【讨论】:
【参考方案4】:实现 ack 的最佳方式是在应用层进行。 CoAP 是在 udp 上运行但提供可靠数据传输的应用程序协议的一个示例。它为所有 Confirmable(CON) 消息保留一个消息 id,并发送一个接收者发送一个具有相同消息 id 的 ack 数据包。所有的 ack 和 message id 字段都保存在应用层部分。因此,如果发送方没有收到带有他发送的消息 id 的 Ack 数据包,它会重新传输该数据包。应用程序开发人员可以修改协议以满足可靠数据传输的需求。
【讨论】:
【参考方案5】:棘手的问题。我会说,你将无法实现 TCP 的可靠性。但是,我确实理解有时,您需要有可靠的 UDP。
Gamedev forum
RUDP(有点硬核)
Old Thread about reliable UDP
【讨论】:
以上是关于通过 UDP 实现 ack?的主要内容,如果未能解决你的问题,请参考以下文章
TCP 三次握手四次挥手, ack 报文的大小.tcp和udp的不同之处tcp如何保证可靠的tcp滑动窗口解释