当您需要可靠的UDP时,您会使用什么?

时间:2008-09-20 08:52:41

标签: sockets tcp network-programming udp

如果您的TCP连接可能太慢并且UDP“连接”可能太不可靠,您使用什么?有各种标准的可靠UDP协议,你有什么经验吗?

请在每个回复中讨论一个协议,如果其他人已经提到您使用过的协议,那么请考虑投票并使用评论进行详细说明。

我对这里的各种选项很感兴趣,其中TCP位于规模的一端而UDP位于另一端。提供了各种可靠的UDP选项,每个选项都带有TCP到UDP的一些元素。

我知道TCP通常是正确的选择,但是有一个替代方案列表通常可以帮助我们得出结论。像UDP,RUDP等基于UDP的东西有各种优点和缺点,你使用过它们,你的经历是什么?

为避免疑问,没有更多的信息,这是一个假设的问题,我希望这个问题会引出一份回复列表,详细说明需要做出决定的人可以使用的各种选项和备选方案。

15 个答案:

答案 0 :(得分:27)

SCTP怎么样?它是IETF(RFC 4960)的标准协议

它具有可以帮助提高速度的分块功能。

更新:comparison between TCP and SCTP表示除非可以使用两个界面,否则表演具有可比性。

更新:nice introductory article

答案 1 :(得分:25)

如果没有关于问题领域的其他信息,很难回答这个问题。 例如,您使用的数据量是多少?多常?数据的性质是什么? (例如,它是唯一的,一个关闭数据?还是一个样本数据流?等等) 你正在开发什么平台? (例如桌面/服务器/嵌入式) 要确定“太慢”的含义,您使用的是什么网络媒体?

但在(非常!)一般术语中,我认为你将不得不尝试非常努力地击败tcp以获得速度,除非你可以对你试图发送的数据做出一些严格的假设。

例如,如果您尝试发送的数据是可以容忍丢失单个数据包(例如,定时采样数据,其中采样率比信号带宽高很多倍),那么你可以通过确保检测到数据损坏(例如通过使用好的crc)来牺牲一些传输可靠性

但是如果你不能容忍丢失单个数据包,那么你将不得不开始介绍tcp已经拥有的可靠性技术类型。并且,如果不进行合理的工作量,您可能会发现您已经开始将这些元素构建到用户空间解决方案中,并解决所有固有的速度问题。

答案 2 :(得分:20)

ENET - http://enet.bespin.org/

我使用ENET作为可靠的UDP协议,并为我的客户在其服务器中使用它编写了一个异步套接字友好版本。它运行得很好,但我不喜欢对等ping增加空闲连接的开销;当你有很多连接时,定期ping所有连接是很繁忙的工作。

ENET为您提供发送多个“通道”数据的选项,以及发送的数据不可靠,可靠或有序。它还包括前面提到的点对点ping,它起着保持活力的作用。

答案 3 :(得分:14)

我们有一些使用UDT(基于UDP的数据传输)的国防工业客户(参见http://udt.sourceforge.net/),并对此非常满意。我看到它也有一个友好的BSD许可证。

答案 4 :(得分:10)

RUDP - Reliable User Datagram Protocol

这提供:

  • 确认收到的数据包
  • 窗口和拥塞控制
  • 重传丢失的数据包
  • 过度缓冲(比实时流更快)

关于保持alive然后ENet似乎稍微可配置但是它没有给你那么多的选项(即所有数据都是可靠的并且不仅仅是你决定的比特序列)。它看起来很容易实现。

答案 5 :(得分:9)

正如其他人所指出的那样,你的问题很普遍,而且某些东西是否比TCP更“快”取决于应用的类型。

TCP通常与从一个主机到另一个主机的可靠数据流传输速度一样快。但是,如果您的应用程序执行大量小突发流量并等待响应,则UDP可能更适合最小化延迟。

有一个容易的中间立场。 Nagle's algorithm是TCP的一部分,有助于确保发送方不会压倒大量数据流的接收方,从而导致拥塞和数据包丢失。

如果您需要TCP的可靠,有序传输以及UDP的快速响应,并且不需要担心发送大量数据流时的拥塞,您可以禁用Nagle的算法:

int opt = -1;
if (setsockopt(sock_fd, IPPROTO_TCP, TCP_NODELAY, (char *)&opt, sizeof(opt)))
  printf("Error disabling Nagle's algorithm.\n");

答案 6 :(得分:7)

任何决定上面列表不够并且他们想要开发自己的OWN可靠UDP的人都应该看看Google QUIC规范,因为这涵盖了许多复杂的角落案例和潜在的拒绝服务攻击。我还没有使用它的实现,你可能不想要或不需要它提供的所有东西,但在开始一个新的“可靠的”UDP设计之前,该文档非常值得阅读。

QUIC的一个很好的起点是here,在Chromium博客上结束。

可以找到当前的QUIC设计文档here

答案 7 :(得分:4)

  

如果您的TCP连接可能太慢并且UDP“连接”可能太不可靠,您使用什么?有各种标准的可靠UDP协议,你有什么经验吗?

句子中的关键词是“潜在的”。我认为你真的需要向自己证明,如果你的协议需要可靠性,TCP实际上对你的需求来说太慢了。

如果你想从UDP获得可靠性,那么你基本上会在UDP之上重新实现一些TCP的功能,这可能会比首先使用TCP更慢。

答案 8 :(得分:4)

协议DCCP,标准化为RFC 4340,“数据报拥塞控制协议”可能正是您所寻找的。

似乎是implemented in Linux

答案 9 :(得分:3)

可能是RFC 5405,“应用程序设计人员的单点UDP使用指南”对您有用。

答案 10 :(得分:2)

您是否考虑过压缩数据?

如上所述,我们缺乏有关问题确切性质的信息,但压缩数据以传输它们可能有所帮助。

答案 11 :(得分:2)

RUDP。许多用于游戏的套接字服务器实现了类似的功能。

答案 12 :(得分:1)

很难对此问题给出一个普遍的答案,但是最好的方法可能不是停留在“ TCP和UDP之间”,而是走到一边:)。

更详细的解释:

如果应用程序需要为其传输的每条数据获得确认响应,则TCP的速度与它获得的速度差不多(特别是如果您的消息比用于连接的最佳MTU小得多),并且您需要发送周期性数据会在您发送出去后立即过期,因此出于多种原因(而不是速度方面),原始UDP是最佳选择。

可靠性是一个更复杂的问题,在两种情况下它都是相对的,并且始终取决于特定的应用程序。举一个简单的例子,如果您从路由器上拔下了互联网电缆,那么祝您好运,并确保可靠地使用TCP传输任何内容。更糟糕的是,如果您不对代码进行任何处理,那么操作系统很可能会在显示错误之前阻塞应用程序几分钟,在许多情况下,这种延迟也是不可接受的。

因此,常规网络协议的问题通常与速度或可靠性无关,而与便利性有关。它不仅要获得TCP的某些功能(自动拥塞控制,自动传输单元大小调整,自动重传,基本连接管理等),还要至少获得它错过的一些重要和有用的功能(消息边界-最重要的是,连接质量监视,连接中的多个流等),而不必自己实现。

从我的角度来看,SCTP现在看起来像是最佳的通用选择,但它并不是很流行,并且可靠地在当今的Internet上传递它的唯一现实方法仍然是将其包装在UDP中(可能使用 sctplib )。它仍然是一个相对基本且紧凑的解决方案,对于某些应用程序来说,仅靠它本身可能还不够。

对于更高级的选项,在某些项目中,我们使用了 ZeroMQ ,并且效果很好。这不仅仅是一个网络协议(它支持TCP,UDP,几个更高级别的协议以及一些实际传递消息的本地IPC机制),而不仅仅是一个完整的解决方案。自发布几个版本以来,其最初的开发人员将注意力转移到了他的新 NanoMSG 以及当前最新的 NNG 库中。它没有经过全面的开发和测试,也不是很流行,但是有一天它可能会改变。如果您不介意CPU开销和某些网络带宽损失,那么某些库可能对您有用。还有其他一些面向网络的消息交换库。

答案 13 :(得分:1)

您应该检查 MoldUDP,它已经存在了几十年,并且被纳斯达克的 ITCH 市场数据提要使用。我们的消息传递系统 CoralSequencer 使用它来实现来自中央进程的可靠多播事件流。

免责声明:我是 CoralSequencer 的开发者之一

答案 14 :(得分:-3)

使用UDP实现可靠性的最佳方法是在应用程序本身中构建可靠性(例如,通过添加确认和重传机制)