通过UDP实现ack?

时间:2009-10-03 20:59:35

标签: c networking tcp udp network-protocols

我们有一个系统(内置于C),可以通过UDP进行通信。最近我们发现有必要保证数据包的传送。我的问题是:基于UDP的系统最少增加什么才能确保使用ack数据包进行传输?此外,理想情况下无需操纵数据包标头。我们对数据包进行应用程序级控制,包括序列号和ack / nack标志。我想知道这是否是一个失败的原因,我们尝试做的任何事情基本上都是一个有缺陷和破坏的TCP版本。基本上,我们可以通过极简主义改进来实现有保证的交付(我们不需要TCP的许多功能,例如拥塞控制等)。谢谢!

5 个答案:

答案 0 :(得分:9)

TCP交织了3个可能相关的服务(好的TCP做得更多,但我只会谈论3个。)

  1. 按顺序交付
  2. 可靠的交付
  3. 流量控制
  4. 你刚才说你不需要流控制,所以我甚至不会解决这个问题(如何宣传窗口大小等等,除非你可能需要一个窗口。我会得到的它。)

    您确实说过需要可靠的送货服务。这不是太难 - 您使用ACK来表明发件人已收到数据包。基本可靠的交付看起来像:

    1. 发件人发送数据包
    2. 接收方收到数据包,然后发送确认
    3. 如果发件人没有获得确认(通过计时器),他会重新发送数据包。
    4. 这三个步骤没有解决这些问题:

      1. 如果ACK丢失怎么办?
      2. 如果数据包无法到达怎么办?
      3. 因此,对于您的应用程序,您说您只需要可靠的交付 - 但没有说明需要它们。这将影响您实施协议的方式。

        (有序无关紧要的例子:你将员工记录从一台计算机复制到另一台计算机。如果Alice的记录在Bob之前收到,只要两者都到达那里就没关系。)

        因此,假设您只需要可靠(因为这就是您在帖子中所说的内容),您可以通过以下几种方式实现这一目标。

        您的发件人可以跟踪未确认的数据包。因此,如果它发送#3,4,5和6,并且没有获得3和4的ACK,则发送方知道它需要重新发送。 (虽然发送者不知道数据包3和4是否很多,或者他们的ACK是否丢失。无论哪种方式,我们都必须重新发送。)

        但是你的发送者可以做累积的ACK - 所以在上面的例子中,如果它已经收到3,4和5,它只会被激活#6。这意味着接收器将丢弃数据包6如果没有收到之前的那些。如果您的网络非常可靠,那么这可能不是一个糟糕的选择。

        但是,上述协议确实有一个窗口 - 即发送方一次发送多少个数据包?这意味着您确实需要某种窗口,但不是出于流量控制的目的。你将如何传输窗口大小?

        你可以在没有窗口的情况下通过窗口大小不变,或者做一些像停止等待的事情来做。前者可能是更好的选择。

        无论如何,我没有直接回答你的问题,但我希望我已经指出了一些在构建这个问题时值得考虑的事情。没有流量控制部分(如窗口)而不考虑有序的“可靠传输”的任务很难! (让我知道我是否应该提供一些关于这些东西的更多细节!)

        祝你好运!

答案 1 :(得分:5)

看看史蒂文UNIX Network Programming, volume 1的第8章和第20章。他介绍了许多不同的方法。第20.5节“为UDP应用程序添加可靠性”可能对您最感兴趣。

答案 2 :(得分:4)

我有一个问题正在运行here,它正在收集“当您需要可靠的UDP时使用什么”的答案。答案可能比您想要或需要的要多得多,但您可以查看一些基于UDP构建的协议,并只获取您需要的ACK部分。

根据我对ENet协议(可靠的UDP协议)的工作,我希望你需要在每个UDP数据报中有一个序列号,一种为你收到的数据报发送ACK的方法,一种保持您发送的数据报,直到您收到他们的ACK或他们超时,并为您尚未收到ACK的数据报的重新发送计时...我还会在您决定的时候添加一个总超时你永远不会提供一个特定的数据报,而且,我想,回调你的应用层,告知它未能提供......

答案 3 :(得分:0)

难题。我会说,你将无法实现TCP的可靠性。但是,我知道有时候,你需要有可靠的UDP。

Gamedev forum

RUDP(更硬一点)

Old Thread about reliable UDP

答案 4 :(得分:0)

实现ack的最佳方法是在应用程序层中执行此操作。 CoAP是在udp上运行但提供可靠数据传输的应用程序协议的示例。它为所有可确认(CON)消息保留消息ID,并发送接收方发送具有相同消息ID的ack数据包。所有ack和message id字段都保存在应用程序层部分。因此,如果发送方没有收到带有他发送的消息ID的Ack数据包,它会重新发送该数据包。应用程序开发人员可以修改协议以满足可靠数据传输所需的需求。