我正在开发一个完全在单个网络中运行的 .net 解决方案。当用户对系统进行更改时,我想发布一个公告,让其他人听到并采取相应的行动。有没有一种方法可以让我们广播出这样的消息(就像 UDP 会让你做的那样),同时保持有保证的传递(比如 TCP)?
这是在一个小型网络(30 多个客户端)上,如果这会有所作为的话。
我正在开发一个完全在单个网络中运行的 .net 解决方案。当用户对系统进行更改时,我想发布一个公告,让其他人听到并采取相应的行动。有没有一种方法可以让我们广播出这样的消息(就像 UDP 会让你做的那样),同时保持有保证的传递(比如 TCP)?
这是在一个小型网络(30 多个客户端)上,如果这会有所作为的话。
几乎所有游戏都需要 UDP 的快速反应特性(在较小程度上还需要无连接特性)和 TCP 的可靠性。他们所做的是在 UDP 之上构建自己的可靠协议。这使他们能够将数据包突发到任何地方,并且还可以选择使它们可靠。
可靠的数据包系统通常是一个简单的重试直到确认系统,比 TCP 更简单,但有些协议远远超出了 TCP 所能提供的范围。
你的情况听起来很简单。您可能能够自己制作最干净的解决方案 - 只需让每个客户端发回“我听到你”的响应并让服务器继续尝试直到它得到它(或放弃)。
如果你想要更多的东西,大多数自定义协议库都在 C++ 中,所以我不确定它们对你有多大用处。但是,我在这里的知识是几年前的-也许现在已经移植了一些协议。嗯... RakNet 和 enet 是我想到的两个 C/C++ 库。
您可以使用Spread进行群组交流。
@epatel - 我支持 SCTP 的建议(我投了赞成票,但还不能评论这里的其他内容)。
SCTP 具有许多出色的功能和灵活性。您可以将连接细分为多个流,并选择每个流的可靠性以及是否有序。或者,使用部分可靠性扩展,您可以控制每条消息的可靠性。
广播不是你想要的。由于可能并且很可能会有连接到该网络的设备不关心您的消息,因此您应该使用多播。与广播消息不同,广播消息必须发送给网络上的每个客户端并由其处理,组播消息只传递给感兴趣的客户端(即那些有意接收这种特定类型的消息并对其采取行动的客户端)。
如果您稍后扩展此系统以使其需要通过大型网络进行路由,则多播可以扩展至此,而广播则不会,因此您获得了可扩展性优势,稍后您可能会欣赏。同时,您消除了交换机和其他不需要看到这些“发生变化”消息的设备的不必要开销。
您可能想查看RFC 3208 “PGM 可靠传输协议规范”。
这是摘要:
实用通用多播 (PGM) 是一种可靠的多播传输
协议,适用于需要从多个源到 多个接收器的有序或无序、无
重复、多播数据传递的应用程序。
PGM 保证组中的接收器要么接收来自传输和修复的所有数据包,要么能够检测到不可恢复的数据包丢失。PGM 专门用作具有基本可靠性要求的多播应用的可行解决方案。其中心设计目标是操作简单,同时适当考虑可扩展性和网络效率。
您可以使用消息代理,例如ActiveMQ。
将消息发布到主题并让客户端注册对该主题的持久订阅,这样即使他们不在线也不会错过任何消息。
Apache ActiveMQ 是用 Java 编写的消息代理以及完整的 JMS 客户端。然而,Apache ActiveMQ 旨在通过多种协议进行通信,例如 Stomp 和 OpenWire,同时支持多种不同语言的特定客户端。
客户端平台支持包括 c# 和 .net
您可以在应用层实现您自己的类似 TCP 的行为。
因此,例如,您会发送 UDP 广播,但随后会期望来自每个主机的回复响应。如果您在 X 秒内没有得到响应,则发送另一个,依此类推,直到达到某种阈值。如果达到阈值(即主机根本没有响应),则报告错误。
不过,要做到这一点,您需要一个预定义的主机列表来期待回复。
创建一个 TCP 服务器。让每个客户端连接。在与客户端的 TCP 协议中,使用以下消息的总大小的 2 字节前缀创建每个数据包。
客户端然后调用read(max_size=2)
套接字来确定下一条消息的大小,然后read(max_size=s)
收集消息。
你得到可靠、有序的消息,简单。您不需要为此使用消息传递框架。
您肯定想研究Pragmatic General Multicast:
虽然 TCP 使用 ACK 来确认发送的数据包组(这对于多播来说是不经济的),但 PGM 使用否定确认 (NAK) 的概念。
对于进一步的 G-diving,您正在寻找的术语是可靠多播。还要看看Multipath TCP。
您可以做的是在广播之后让客户端启动 tcp 连接。否则,您只需要保留所有客户端的列表并自己启动与每个客户端的连接。
从广义上讲,我认为有三种选择:
Yoy 应该看看 Norm(面向 NACK 的可靠多播)规范。您可以在此处找到有关 Norm 的信息。
NORM 协议旨在通过通用 IP 多播路由和转发服务提供批量数据对象或流的端到端可靠传输。NORM 使用选择性否定确认 (NACK) 机制来保证传输可靠性,并提供额外的协议机制来执行可靠的多播会话,而发送者和接收者之间的“先验”协调有限
它在军事界有点众所周知。
如果可以使用库,为什么要从头开始构建?特别是对于这么小的项目?
尝试使用Emcaster,它本身使用可靠的多播消息传递 - PGM,它是用 .NET 编写的并具有完整源代码。您将获得带有主题过滤功能的不错的发布/订阅引擎。或者你可以从代码中学习如何做,并以此为基础你自己的扩展。
我认为在这些场景中 TCP 最令人恼火的特性是将传入数据包排序为原始顺序的能力/方式 - 流的概念。在它到达之前的字节之前,您无法读取一个字节。
如果你可以没有它,你就有机会拥有你的协议,快速可靠,但不是为了数据包的排序!根本不可能同时管理它们,因为在收到丢失数据包的另一个副本之前,您无法对字节进行排序,这是主要的权衡。
做一个 RDP 多播。