【问题标题】:Looking for best approach to sending the same data to multiple destinations using sockets寻找使用套接字将相同数据发送到多个目的地的最佳方法
【发布时间】:2013-02-07 00:49:21
【问题描述】:

寻找使用 TCP/IP 套接字将相同消息发送到多个目标的最佳方法。我正在使用 Windows 上现有的 VS 2010 C++ 应用程序。希望尽可能使用已经解决了许多复杂性的标准库/设计模式方法。

这是我正在考虑的一种方法。一个主线程从数据库中检索消息并将它们添加到某种线程安全队列中。应用程序还为每个客户端套接字连接到某个目标服务器有一个线程。这些线程中的每一个都将从线程安全队列中读取,并通过 tcp/ip 套接字发送消息。 不过,可能有比这更好/更简单/更强大的方法..

我必须关心的主要问题是延迟。目的地可能在任何地方,并且一个套接字连接和另一个套接字连接之间可能存在显着延迟。 消息必须按照准确的 FIFO 顺序到达所有目的地。

还有一个目的地将被视为主要目的地。所有消息都必须到达此目的地,没有例外。对于其他目的地,即非主要目的地,消息只是副本,如果非主要目的地没有收到一些消息,这并不是绝对关键的。在任何时候,非主要目的地之一都可能成为主要目的地。如果其中一个目的地远远落后,那么该线程将需要赶上主要目的地,但会跳过一些消息。

寻找任何建议。到目前为止的初步研究,我的情况似乎类似于单生产者和多消费者模式,或者可能是 Java 中的主从模式。

我需要在 Windows 上用 C++ 实现这一点,并且应用程序必须使用现有定义的协议使用 tcp/ip 套接字。

任何帮助都将不胜感激。

【问题讨论】:

  • 我不知道“现有定义的协议”是什么意思,但看看ZeroMQ
  • TCP 已经做了很多这样的事情:保证 FIFO 排序,首先,只要与主要目的地(或任何目的地)的连接保持正常,该目的地的对等方就会收到发送的所有数据。从您的描述中,我不清楚为什么延迟如此令人担忧:例如,它不会影响订购。
  • “现有定义的协议”对我来说只是意味着应用程序正在与已经定义接口/协议的服务器通信。这意味着 TCP/IP 是一项要求。
  • 是的,我了解 TCP 保证的 FIFO 排序,并且 TCP/IP 是此应用程序的要求。本质上,该架构是一个客户端将完全相同的消息发送到多个服务器。 ZeroMQ 将此称为扇出。一个客户端将需要向大约 12 个服务器发送相同的消息。客户端每秒将向所有 12 台服务器发送大约 10 千比特的消息。
  • 我之所以提到延迟作为一个问题是因为客户端将每周 7 天/每天 24 小时每秒向所有 12 台服务器发送价值 10 kb 的消息。如果其中一台服务器落后,它永远不会赶上,而且永远会落后。唯一关键的是一台主服务器获取所有消息,其他 11 台服务器可以丢弃一些消息,以便非主服务器赶上主服务器。希望我已经更好地解释了这一点。

标签: c++ multithreading sockets queue


【解决方案1】:

您恰好需要两个线程,一个使 IO 通道饱和到数据库,另一个使 IO 通道饱和到通向 12 个服务器的网络。除非您有多个网络接口(您应该考虑一下!),否则您不会通过使用多个线程来更快地发送信息。此外,由于您没有多个线程来处理网络,因此您不必同步它们。

您绝对需要了解的是 select()。在 WinSock 的情况下,还请查看 WSAEventSelect/WaitForMultipleObjects。基本上,您从队列中获取一条消息,然后在它们准备好时将其发送给所有客户端。 select() 会告诉您一组套接字中的一个何时准备好接受数据,因此您不会浪费时间等待或阻止尝试发送数据。您需要想出的是在连接断开后重新连接的架构,何时将消息发送到滞后的客户端等。此外,如果不同目标的吞吐量变化很大,您需要考虑并行处理多条消息。如果它们很小(小于网络数据包的有效负载),无论如何将它们组合起来以避免开销是有意义的。

我希望这个简短的概述可以帮助您入门,否则我可以详细说明细节。

【讨论】:

    猜你喜欢
    • 2011-10-30
    • 1970-01-01
    • 1970-01-01
    • 2020-04-24
    • 1970-01-01
    • 1970-01-01
    • 2016-05-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多