2008-08-28 43 views
20

我正在处理完全在单个网络内运行的.net解决方案。当用户对系统进行更改时,我想发布一条通知并让其他人都能听到并据此采取行动。有没有一种方法可以像这样广播消息(就像UDP可以让你这样做),同时保证交付(如TCP)?广播像TCP与TCP的可靠性

这是在一个小网络(30个客户端)上,如果这样做会有所作为。

回答

15

几乎所有的游戏都需要UDP的快速反应属性(以及较小程度的无连接属性)和TCP的可靠性。他们所做的是在UDP之上建立自己的可靠协议。这使得他们可以将数据包分组发送到任何地方,并可选地使数据包可靠。

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

你的情况听起来很简单。你可能会自己做出最干净的解决方案 - 让每个客户都回复一个“我听到你”的回应,并让服务器继续尝试,直到它得到它(或放弃)。

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

+0

关于*“超出TCP可以提供的方式”*,那么TCP如何专门用于解决可靠的交付问题,这怎么可能? TCP在可靠的数据包系统中缺少什么? – Pacerier 2015-02-12 04:17:18

+0

@Pacerier如果在流中缺少一小部分,TCP将使用它已经收到的数据。也许在某些情况下,需求是不同的 - 即使数据到达时也会获取数据,即使数据出现故障。 – 2018-02-27 13:59:40

-3

做一个RDP多播。

+0

没有TCP多播,我会对此进行投票,但我没有足够的声望。 – tialaramex 2008-09-17 10:39:27

0

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

0

我认为有三个选项,从广义上说:

  1. 相反广播UDP的,你可以创建一个实体(线程,进程,服务器,服务,或任何事情是在你的解决方案存在),它保存订户列表并向它们发送单播UDP消息。
  2. 使用UDP多点传送,但是你必须编写某种机制来为你提供可靠的传送(即重试,超时等)。这也意味着你必须得到你的客户的答复。
  3. 如果你不害怕的实验传输协议,你可能看here的建议,
7

你可以使用Spread做群组通信。

+0

我会继续这个。使用别人的图书馆是你最好的选择,让这个正确。 – 2008-11-23 15:01:15

+1

@JayKominek,取决于谁是“别人”。 – Pacerier 2015-02-11 12:36:52

1

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

因此,例如,你会发送UDP广播,但期待每个主机的回复响应。如果您在X秒内没有收到回复,则发送另一个等等,直到达到某种阈值。如果达到阈值(即主机完全没有响应),则报告错误。

要做到这一点,你需要一个预先定义的主机列表,以期望得到回应。

11

看看sctp具有TCP和UDP功能的组合。有一个窗口implementation可用。

+1

+1表示sctp。但是,sctp确实没有时间成熟,比TCP或UDP更成熟。很多驱动程序,nics和交换机都没有像TCP那样对它进行超级优化。这里有一个有趣的性能比较 - http://datatag.web.cern.ch/datatag/WP3/sctp/tests.htm – quixver 2013-08-30 16:17:47

0

同比应该看一看的标准(面向NACK的可靠组播)规范。你可以找到information about Norm here

的NORM协议被设计为提供 批量数据对象的端至端可靠传输 或流过 通用IP组播路由和 转接服务。 NORM使用 选择性的,否定确认 (NACK),用于传输 可靠性机制,并提供额外的 协议机制 发送者和接收者

它稍微间与 有限的“先验”协调进行 可靠多播会话在军事世界中非常知名。

Norm specs.

Norm Source

3

@epatel - 我的第二个建议,SCTP(我投了,但不能在这里评论却又如此额外的东西)。

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

1

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

如果以后扩展该系统,以便它需要路由在大型网络中,多播可以扩展到,而广播也不会,所以你得到你以后可能会欣赏的可扩展性的好处。同时,您可以避免在不需要看到这些“更改内容”消息的交换机和其他设备中消除不必要的开销。

2

你可能要考虑RFC 3208“PGM可靠传输协议规范”。

这里是抽象:

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

0

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

尝试使用Emcaster,它本身使用可靠的多播消息传递 - PGM,是用.NET编写的并且具有完整源代码。你会得到很好的酒吧/子引擎与主题过滤随时可用。或者您可以从代码中学习如何做到这一点,并在其上创建自己的扩展。

0

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

如果你没有它,你有机会拥有你的协议,快速和可靠的,但不是订购数据包!要管理它们是根本不可能的,因为在收到丢失数据包的其他副本之前,您无法排序字节,这是主要的折衷。

1

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

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

您得到可靠的,有序的消息,很简单。你不需要这个消息框架。

2

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

的Apache ActiveMQ是一个完整的 JMS客户端用Java编写的一起消息代理 。然而,Apache ActiveMQ是 ,其设计用于通过诸如Stomp和 OpenWire等协议的数字进行通信,并且支持 号码的不同语言特定的 客户端。

客户端平台支持包括C#和.NET