【发布时间】:2010-09-07 02:10:25
【问题描述】:
我正在开发一个完全在单个网络中运行的 .net 解决方案。当用户对系统进行更改时,我想发布一个公告,让其他人听到并采取相应的行动。有没有一种方法可以让我们广播出这样的消息(就像 UDP 会让你做的那样),同时保持有保证的传输(如 TCP)?
这是在一个小型网络(30 多个客户端)上,如果这会有所作为的话。
【问题讨论】:
标签: .net networking tcp udp
我正在开发一个完全在单个网络中运行的 .net 解决方案。当用户对系统进行更改时,我想发布一个公告,让其他人听到并采取相应的行动。有没有一种方法可以让我们广播出这样的消息(就像 UDP 会让你做的那样),同时保持有保证的传输(如 TCP)?
这是在一个小型网络(30 多个客户端)上,如果这会有所作为的话。
【问题讨论】:
标签: .net networking tcp udp
几乎所有游戏都需要 UDP 的快速反应特性(在较小程度上还需要无连接特性)和 TCP 的可靠性。他们所做的是在 UDP 之上构建自己的可靠协议。这使他们能够将数据包突发到任何地方,并且还可以选择使它们可靠。
可靠的数据包系统通常是一个简单的重试直到确认系统,比 TCP 更简单,但有些协议远远超出了 TCP 所能提供的范围。
你的情况听起来很简单。您可能能够自己制定最干净的解决方案 - 只需让每个客户端发回“我听到了”响应并让服务器继续尝试直到它得到它(或放弃)。
如果您想要更多内容,大多数自定义协议库都使用 C++,所以我不确定它们对您有多大用处。但是,我在这里的知识是几年前的-也许现在已经移植了一些协议。嗯... RakNet 和 enet 是我想到的两个 C/C++ 库。
【讨论】:
看看sctp,它结合了 tcp 和 udp 功能。有一个窗口implementation 可用。
【讨论】:
您可以使用Spread进行群组交流。
【讨论】:
@epatel - 我支持 SCTP 的建议(我投了赞成票,但还不能在这里发表评论)。
SCTP 具有许多出色的功能和灵活性。您可以将连接细分为多个流,并选择每个流的可靠性以及是否有序。或者,使用Partially Reliability 扩展,您可以控制每条消息的可靠性。
【讨论】:
广播不是你想要的。由于可能并且很可能会有连接到该网络的设备不关心您的消息,因此您应该使用多播。与必须向网络上的每个客户端发送并由其处理的广播消息不同,多播消息仅传递给感兴趣的客户端(即那些有意接收这种特定类型的消息并对其采取行动的客户端)。
如果您稍后扩展此系统以使其需要通过大型网络进行路由,则多播可以扩展至此,而广播则不会,因此您获得了可扩展性优势,稍后您可能会意识到这一点。同时,您消除了交换机和其他不需要看到这些“发生了变化”消息的设备的不必要开销。
【讨论】:
您可能想查看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,您要查找的术语是 reliable multicast。也可以看看Multipath TCP。
【讨论】:
您可以做的是在广播之后让 客户端 启动 tcp 连接。否则,您只需保留所有客户端的列表并自己启动与每个客户端的连接。
【讨论】:
从广义上讲,我认为有三种选择:
【讨论】:
Yoy 应该看看 Norm(面向 NACK 的可靠多播)规范。你可以找到information about Norm here。
NORM 协议旨在 提供端到端的可靠传输 大量数据对象或流 通用 IP 多播路由和 转发服务。 NORM 使用 选择性否定确认 (NACK) 传输机制 可靠性并提供额外的 协议机制进行 可靠的多播会话 有限的“先验”协调 发送者和接收者
它在军事界非常有名。
【讨论】:
如果可以使用库,为什么要从头开始构建?尤其是这么小的项目?
尝试使用Emcaster,它本身使用可靠的多播消息传递 - PGM,它是用 .NET 编写的并具有完整源代码。您将获得带有主题过滤功能的不错的发布/订阅引擎。或者你可以从代码中学习如何做,并以此为基础你自己的扩展。
【讨论】:
我认为在这些场景中 TCP 最令人讨厌的特性是能够将传入数据包按原始顺序排序的能力/方式 - 流的概念。在字节到达之前的字节之前,您无法读取字节。
如果你可以没有它,你就有机会拥有你的协议,快速可靠,但不是为了数据包的排序!根本不可能同时管理它们,因为在收到丢失数据包的另一个副本之前,您无法对字节进行排序,这是主要的权衡。
【讨论】:
进行 RDP 多播。
【讨论】: