像UDP一样广播,具有TCP的可靠性

时间:2008-08-28 02:55:23

标签: .net networking tcp udp

我正在开发一个完全在单个网络中运行的.net解决方案。当用户对系统进行更改时,我想发布一个通知,让其他人听到并做出相应的操作。有没有一种方法可以广播这样的消息(比如UDP会让你这么做),同时保证有保证的交付(比如TCP)?

这是在一个小型网络(30个客户端),如果这会产生影响。

16 个答案:

答案 0 :(得分:15)

几乎所有游戏都需要UDP的快速反应属性(在较小程度上,无连接属性)和TCP的可靠性。他们所做的是在UDP之上构建自己的可靠协议。这使他们能够将数据包突发到任意位​​置,并且可选地使它们可靠。

可靠的数据包系统通常是一个简单的重试直到确认的系统,比TCP简单,但有些协议超出了TCP提供的范围。

你的情况听起来很简单。您可能自己能够制作最干净的解决方案 - 只需让每个客户端发回“我听到你”的响应并让服务器继续尝试直到它得到它(或放弃)。

如果你想要更多东西,大多数自定义协议库都是用C ++编写的,所以我不确定它们对你有多大用处。但是,我在这里的知识还有几年的历史 - 现在可能已经移植了一些协议。嗯...... RakNet和enet是我想到的两个C / C ++库。

答案 1 :(得分:10)

查看具有tcp和udp功能组合的sctp。有一个可用的窗口implementation

答案 2 :(得分:7)

您可以使用Spread进行群组通讯。

答案 3 :(得分:3)

@epatel - 我的第二个SCTP建议(我投票了,但是还不能评论这里有更多的东西)。

SCTP具有许多强大的功能和灵活性。您可以将连接细分为多个流,并选择每个流的可靠性以及是否已订购。或者,使用Partially Reliability扩展名,您可以基于每条消息控制可靠性。

答案 4 :(得分:2)

广播不是你想要的。由于可能并且可能会有连接到此网络的设备不关心您的消息,因此您应该使用多播。与广播消息不同,广播消息必须由网络上的每个客户端发送和处理,多播消息仅传递给感兴趣的客户端(即那些有意接收此特定类型消息并对其进行操作的客户端)。

如果您稍后扩展此系统以便需要在大型网络上进行路由,则多播可以扩展到该系统,而广播则不会,因此您可以获得可扩展性优势,以后可能会对此表示赞赏。同时,您可以消除交换机和其他不需要查看这些“更改内容”消息的设备的不必要开销。

答案 5 :(得分:2)

您可能需要查看RFC 3208“PGM可靠传输协议规范”。

以下是摘要:

  

实用通用多播(PGM)   是一种可靠的多播传输方式   需要的应用程序协议   有序或无序的,
  无重复的组播数据   从多个来源交付到   多个接收器。 PGM保证   组中的接收器也是   从中接收所有数据包   传输和维修,或者是   能够检测不可恢复的数据   数据包丢失。 PGM是具体的   打算作为一个可行的解决方案   基本的组播应用程序   可靠性要求。它的核心   设计目标是简单   适当考虑的操作   可扩展性和网络效率。

答案 6 :(得分:2)

您可以使用消息代理,例如ActiveMQ 将您的消息发布到主题并让客户注册该主题的持久订阅,这样即使他们不在线,他们也不会错过任何消息。

  

Apache ActiveMQ是一个消息代理   用Java写的一个完整的   JMS客户端。但Apache ActiveMQ是   旨在通过数字进行通信   Stomp和。等协议   OpenWire与支持一起   特定语言的数量   客户端。

客户端平台支持包括c#和.net

答案 7 :(得分:1)

您可以在应用程序层实现自己的类似TCP的行为。

因此,例如,您发送UDP广播,但随后期望来自每个主机的回复响应。如果你没有在X秒内得到响应,那么发送另一个,依此类推,直到达到某种阈值。如果达到阈值(即主机完全没有响应),则报告错误。

要做到这一点,你需要一个预定义的主机列表来期待回复。

答案 8 :(得分:1)

创建TCP服务器。让每个客户连接。在与客户端的TCP协议中,使用以下消息总大小的2字节前缀创建每个数据包。

客户端然后在套接字上调用read(max_size=2)以确定下一条消息的大小,然后read(max_size=s)收集消息。

您获得可靠,有序的消息,简单。您不需要这个消息传递框架。

答案 9 :(得分:1)

绝对想要调查Pragmatic General Multicast

  

虽然TCP使用ACK来确认发送的数据包组(在多播上不经济),但PGM使用否定确认(NAK)的概念。

对于进一步的G-diving,您要查找的字词是reliable multicast。另请查看Multipath TCP

答案 10 :(得分:0)

您可以做的是广播后客户端启动tcp连接。否则,您只需保留所有客户的列表,并自行启动与每个客户的连接。

答案 11 :(得分:0)

我认为有三种选择,广义而言:

  1. 您可以创建一个实体(一个线程,进程,服务器,服务或解决方案中存在的任何东西)来保存订阅者列表并向其发送单播UDP消息,而不是广播UDP。
  2. 使用UDP多播,但您必须编写某种机制来处理可靠的交付(即重试,超时等)。这也意味着您必须得到客户的回复。
  3. 如果您不担心实验性传输协议,可以查看here以获取建议。

答案 12 :(得分:0)

Yoy应该看一下Norm(NACK-Oriented Reliable Multicast)规范。您可以找到information about Norm here

  

NORM协议旨在   提供端到端可靠的运输   批量数据对象或流   通用IP组播路由和   转发服务。 NORM使用a   选择性,否定性承认   (NACK)运输机制   可靠性和额外提供   协议机制进行   可靠的多播会话   有限的“先验”协调   发送者和接收者

在军事界有点非常有名。

Norm specs.

Norm Source

答案 13 :(得分:0)

如果可以使用库,为什么要从头开始构建?特别是对于这样的小项目?

尝试使用Emcaster本身使用可靠的多播消息传递 - PGM,用.NET编写并具有完整的源代码。你会得到很好的pub / sub引擎,主题过滤随时可用。或者您可以从代码中学习如何操作并在其上建立自己的扩展。

答案 14 :(得分:0)

我认为TCP在这些场景中最令人恼火的特征是将传入数据包按原始顺序排序的能力/方式 - 流的概念。在它到达之前的字节之前,你不能读取一个字节。

如果没有它,你就有机会拥有快速可靠的协议,但不能订购数据包!管理它们是根本不可能的,因为在收到丢失数据包的其他副本之前你不能命令你的字节,这是主要的权衡。

答案 15 :(得分:-3)

执行RDP多播。