一个可靠的UDP实现

7
我需要实现一个符合以下标准的UDP:
  • 可在Linux和Mac上使用(只关心最新版本)
  • 可从C ++中使用
  • 对数据包排序
  • 保证数据包传递
  • 非面向连接(类似UDP)
注意:我不想使用TCP。 注意:它可以由任何套接字API实现,只要它在两个平台上可用并且可供C ++使用。
编辑: 我已经查看了UDT,RUDP和SCTP。这些似乎是主要的竞争者。有什么想法吗?
编辑: UDT似乎就是我要找的东西。它是否在内核的UDP上实现的用户空间会带来巨大的性能问题?还是速度比TCP / STCP更快?
编辑(2/15/12): 我想出了一个解决方案,它使用TCP和中央重定向服务器。该系统允许一个客户端通过始终打开的TCP连接将数据发送到服务器,服务器再通过其与第二个客户端的TCP连接将其传递给正确的其他客户端。

7
如果你想要做到 TCP 所能做的一切,并失去使用 UDP 的所有理由,那么如果你想得到好的 / 有用的答案,你应该为不使用 TCP 给出一个充分的理由。 - Michael Anderson
3
如果你想要有序、保证的分组传递,这难道不会使它变成面向流吗? - Carl Norum
可能是因为UDP是无连接的? - ta.speot.is
4
以后就不再是无连接的了,因为你需要跟踪哪些收件人尚未接收到特定的数据包。 - Ben Voigt
2
@BenVoigt的评论是关键。即使您使用类似UDP的协议发送数据包,发送方和接收方现在都需要维护状态以实现可靠性。这种状态基本上就是一个连接。 - smparkes
显示剩余9条评论
6个回答

4

这是一个老问题,但我看到没有人回答UDT相关的内容。我有一些经验,可以分享一下。

UDT非常好用。基本上你可以像使用UDP套接字一样使用它,并从中获得你所列出的所有东西。

就性能而言,我没有注意到任何问题。实际上,它具有几种算法来最大化吞吐量,你可以获得相当惊人的结果(在100 MB/s以太网局域网上,我获得了>90 MB/s)。它也可以在慢速/高延迟的链接上正常工作。

当然,它不是完美的,某些错误场景没有被处理得我满意,但大部分情况下,你只需要“插入”它,就可以了。


谢谢!(我是楼主)。这个项目对我来说没有进展,但将来有这些信息还是很好的。 - Linuxios

2
我认为你想要的是 SCTP

我知道这个有一个FLA,但是我只能找到RTSP。错了一个字母。看起来他们有一个OS X内核扩展。 - smparkes

1

这个教程系列可能会引起您的兴趣。

编辑:下一个教程的链接在页面底部,可靠UDP的帖子实际上是第三篇,但第一篇和第二篇也值得一读。


1

免责声明:我在一家生产商业UDP数据传输工具的公司工作。

市面上有很多UDP数据传输工具,包括免费软件和商业软件。你选择哪一个将取决于除你已经提到的因素之外的几个因素:

  • 你要传输什么类型的数据?文件、程序生成的数据流、短消息?以千字节、兆字节、千兆字节或万亿字节为单位?大多数UDP解决方案都专注于文件或大型数据流。很少有针对小型或通用消息进行优化的。

  • 你的网络拓扑结构是什么?客户端-服务器、点对点、服务器-服务器?这将影响防火墙问题,并可能影响商业解决方案的成本。

  • 你希望部署在什么样的网络环境中?一些基于UDP的传输协议只适用于非常快速的网络或用户能够配置正确目标速度的网络。其他协议则针对低速、高延迟(如卫星)进行了优化。有些协议在任何环境下都表现良好。

  • 你愿意花多少钱?既有开源解决方案,也有商业解决方案。商业解决方案的价格差异巨大,可能取决于上述某些因素。

  • 你需要多少支持?一些开源解决方案周围有强大的社区,而有些几乎被遗弃。同样,商业解决方案的支持水平也有所不同。

显然,我正在努力把握一个微妙的平衡,为您提供需要考虑的事情,而不是推销我的公司。如果我偏向任何一方,对此我深表歉意。


你能否列举一些开源的小型消息传递的替代方案,基于客户端-服务器模式,用于在线游戏,精度不是非常重要(每秒仅约3个位置更新,大多数消息少于20字节)? - Steve
1
对于这种情况,您真的不需要流程控制或错误恢复:只需发送数据报即可。重要的是确保您的位置是绝对的(而不是相对的),以便任何一个消息的丢失都是无害的。您需要排序,因此在每个数据包中发送序列号,在接收器处记录最高编号,并忽略任何具有较小编号的数据包。 - Seth Noble
你误解了我的意思 - 它还发送其他重要的消息(例如服务器计算的伤害等),位置只是其中一个例子,所有这些消息都会被发送。 - Steve
我没有使用过它,但你可以尝试类似于开放游戏协议的东西。那可能有点过头了。考虑一下是否可以使每个消息都是独立的(当前健康状况而不是造成的伤害),而不必遭受从恢复丢失的数据包中遭受延迟的痛苦。如果总统计数据太大而无法适应一个数据报,则将其中一些数据分解:例如,每隔一条消息只包含一些统计数据。 - Seth Noble

0

你可能正在寻找RTI-DDS。它有一个C++ API和一个QoS,可以保证通过UDP传递。不确定是否支持Mac,但你可以通过support@rti.com向他们询问。


0

听起来你想要的是类似于RUDP的东西。

无论如何,这个实现起来非常复杂。我不知道有什么可以做到这一点的。

我还想强调一下,如果这不是在内核中完成的话,性能会急剧下降。通常在应用程序中执行诸如数据包重组等操作要求更多的缓冲区或者在数据速率足够高的情况下会产生更多的重试(这可能是相当少量的流量)。


我认为Linux在Berkley Sockets API中实现了RUDP,但是我不确定Darwin是否也实现了。你知道吗? - Linuxios
不,我没有。正如你所提到的,这方面有许多协议,但是通用实现很少。 - smparkes
我也可以完全避免在 Mac 上运行,只需在 Mac 上运行 Linux 虚拟机。我想我会使用 RUDP。 - Linuxios
你知道在Linux Berkeley Sockets API中如何使用RUDP的任何文档吗?我找不到任何东西。 - Linuxios

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接