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

19
我正在开发一个完全在单个网络内运行的.NET解决方案。当用户对系统做出更改时,我想发布公告并让其他人听到并采取相应措施。是否有一种方法可以像使用UDP那样广播这些消息,同时保证交付(就像TCP一样)?
如果只有30个客户端的小型网络,则可能会有所不同。
16个回答

15
几乎所有游戏都需要UDP的快速反应特性(在较小程度上需要无连接特性)和TCP的可靠性。他们所做的是在UDP之上构建自己的可靠协议。这使得它们能够将数据包迅速发送到任何地方并选择性地使它们可靠。
可靠的数据包系统通常是一个简单的重试直到收到确认消息的系统,比TCP更简单,但有些协议超越了TCP所能提供的功能。
您的情况听起来非常简单。您可能能够自己制定最干净的解决方案 - 只需让每个客户端发送回一个“我听到你”的响应,并让服务器不断尝试直到获得响应(或放弃)。
如果您想要更多内容,大多数自定义协议库都是用C++编写的,因此我不确定它们对您有多大用处。然而,我的知识已经过时了几年 - 也许现在已经有一些协议被移植了过来。嗯... RakNet和enet是我想到的两个C / C ++库。

关于“远远超出TCP所能提供的”这一点,这是怎么可能的呢?因为TCP专门用于解决可靠传输问题。难道TCP在可靠数据包系统方面存在缺陷吗? - Pacerier
1
TCP会保留已经接收到的数据,如果流中有任何一小部分缺失。也许在某些情况下要求不同-即使数据是无序的,也要尽快获得它到达的数据。 - Tomas Andrle

10

看一下 SCTP,它具有tcp和udp的特性组合。有一个可用于windows的实现


1
+1 建议使用 SCTP。然而,与 TCP 或 UDP 相比,SCTP 还没有成熟的时间。许多驱动程序、网卡和交换机并没有像 TCP 那样进行超级优化。这里有一个有趣的性能比较 - http://datatag.web.cern.ch/datatag/WP3/sctp/tests.htm。 - quixver

7
您可以使用Spread来进行群组通信。

我赞同这个观点。使用别人的库是你获得正确结果的最佳选择。 - Jay Kominek
1
@JayKominek,这取决于“别人”是谁。 - Pacerier

3

@epatel - 我支持SCTP建议(我投了赞成票,但还不能发表评论,所以在这里补充一些内容)。

SCTP具有许多出色的功能和灵活性。您可以将连接分成多个流,并选择每个流的可靠性以及它是否有序。或者,使用部分可靠性扩展,您可以按消息基础控制可靠性。


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

Apache ActiveMQ是一个消息代理,使用Java编写,同时具有完整的JMS客户端。但是,Apache ActiveMQ旨在通过多种协议(如Stomp和OpenWire)进行通信,并支持许多不同的语言特定客户端。

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


2
您可能想了解一下RFC 3208“PGM可靠传输协议规范”。
以下是摘要:
引用: Pragmatic General Multicast(PGM)是一种可靠的多播传输协议,适用于需要从多个源到多个接收者有序或无序、无重复的多播数据传递的应用程序。 PGM保证组中的接收者可以接收来自传输和修复的所有数据包,或者能够检测到不可恢复的数据包丢失。 PGM的设计目标是实现基本可靠性要求的多播应用程序的可行解决方案。其核心设计目标是简单易用,同时考虑到可扩展性和网络效率。

2
广播不是你想要的。因为可能会有设备连接到这个网络,它们并不关心你的消息,所以你应该使用组播。与必须发送到网络上每个客户端并由其处理的广播消息不同,组播消息仅传递给感兴趣的客户端(即那些有意接收此特定类型消息并对其采取行动的客户端)。
如果您稍后将此系统扩展到需要在大型网络上路由,则组播可以扩展到该网络,而广播则不能,因此您可以获得可伸缩性优势,这可能会在以后受益。同时,您还可以消除交换机和其他不需要看到这些“某些内容已更改”消息的设备中的不必要开销。

你无法从问题中得知这点,例如在无线领域,当消息通过空气发送时,你将被阻止进入网络,因此广播始终更有效率,读取并忽略它是微不足道的成本。一些用例运行专用网络,例如矿井、传感器网络、控制系统等等。 - user1496062
1
不是“广播更有效率”,恰恰相反,这就是我的观点。 - tialaramex

1
创建一个TCP服务器,使每个客户端都能连接上。在与客户端进行TCP协议时,使用2字节前缀来表示接下来消息的总大小。
然后,客户端通过套接字调用read(max_size = 2)来确定下一条消息的大小,然后使用read(max_size = s)来收集该消息。
这样你就可以获得可靠、有序的消息,非常简单。你不需要为此使用消息框架。

现在有大约30个客户,未来可能会增加到几百个。您打算如何支持这些客户? - Pacerier

1
你肯定会想了解实用通用组播

TCP使用ACK来确认发送的数据包组(在组播中这是不经济的),而PGM使用负面确认(NAKs)的概念。

进一步研究时,你要找的术语是可靠组播。还要看看多路径TCP


1

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

例如,你可以发送UDP广播,但是期望每个主机都回复响应。如果在X秒内没有收到响应,则发送另一个请求,直到达到某种阈值。如果达到了阈值(即主机根本没有响应),则报告错误。

不过,要做到这一点,你需要预先定义一个主机列表,以便从中期望收到响应。


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