快速跨平台的C++进程间通信

21

我正在寻找一种方法,使两个程序能够高效地在Linux和Windows系统中传输大量数据。这是一个P2P网络程序的背景,该程序作为网络上的节点持续运行,并且其他应用程序(可能是游戏,因此需要快速的解决方案)将使用它来与网络中的其他节点通信。如果有更好的解决方案,我会很感兴趣。


5
我对这个问题有点不确定…您是在询问在同一台主机上的两个进程之间传输数据,还是在运行在不同主机上(或可能在不同主机上)的两个进程之间传输数据? - Jeremy Friesner
如果你正在寻找更好的解决方案,那么你现在在做什么? - ergosys
@Jeremy:抱歉,我表达不清楚。这两个进程在同一台机器上。 - Stephen Cross
@ergosys:我在问是否有更好的方法,而不仅仅是常规的 IPC……也许通过从一个应用程序传递套接字到另一个应用程序,这样应用程序就可以直接通过套接字发送数据(我不知道这是否可能……如果两个应用程序想要与同一节点通信,这可能会有问题)。 - Stephen Cross
6个回答

17

boost::asio是一个跨平台库,用于处理套接字上的异步 io。你可以结合使用Google Protocol Buffers(一种实际消息格式)。

此外,Boost 还提供了boost::interprocess,用于在同一台机器上进行进程间通信,但是 asio 让您可以异步进行通信,并且可以轻松地为本地和远程连接使用相同的处理程序。


好的,看起来使用boost是解决这个问题的方法...我已经在使用boost::signal了,而且我可能会使用它来处理boost::asio。 - Stephen Cross
使用Google Protocol Buffers,您可以从许多可用的RPC实现中进行选择。 - Grzegorz Wierzowiecki

5

我一直在使用ZeroC的ICE (www.zeroc.com),它非常棒。非常易于使用,不仅跨平台,而且还支持许多语言(如python、java等),甚至还有嵌入式版本的库。


1
ICE 要求您将程序发布在 GPL 下或购买商业许可证,这可能会对 OP 造成问题或不造成问题。 - villintehaspam
1
该程序本身将在GPL下获得许可,因此这不是问题。 - Stephen Cross
ZeroC 使用 Google Protocol Buffers。 - Grzegorz Wierzowiecki
ZeroC Ice确实支持Google Protocol Buffers,但不依赖于也不需要Protocol Buffers。请参阅http://www.zeroc.com/labs/protobuf/index.html了解详情。 - rcv

3
好的,如果我们可以假设这两个进程运行在同一台机器上,那么它们之间传输大量数据的最快方法是将数据保留在共享内存区域中;在这种设置下,由于两个进程都可以直接访问数据,因此根本不需要复制数据。(如果你想更进一步,你可以将这两个程序合并成一个程序,每个以前的“进程”现在作为线程在同一进程空间内运行。在这种情况下,它们会自动与彼此共享100%的内存)
当然,在大多数情况下,仅仅拥有一个共享内存区域是不够的:你还需要某种同步机制,以便进程可以安全地读取和更新共享数据,而不会相互干扰。我会在共享内存区域中创建两个双端队列(每个进程都要发送一个)。要么使用无锁FIFO-queue类,要么给每个双端队列分配一个信号量/互斥量,用于串行化将数据项目推入队列和弹出数据项目。注意,你将放入队列的数据项只是指向实际数据缓冲区的指针,而不是数据本身...否则,你将反复复制大量数据,这是要避免的。最好使用shared_ptrs而不是普通的C指针,这样当接收进程使用完“旧”数据时,它将自动释放。一旦做到了这一点,你唯一需要的另一件事情就是,让A进程在向B进程发送一个项目后通知B进程,以及反之...我通常通过向另一个进程正在select()上的管道中写入一个字节来完成这个操作,从而导致另一个进程唤醒并检查其队列,但也有其他方法可以实现。

1

这是一个难题。

瓶颈在于互联网,以及您的客户可能在NAT后面。

如果您不谈论互联网,或者明确没有客户在运营商级别的恶意NAT后面,您需要说明。

因为问题归结为:使用TCP。接受它。


这两个进程在同一台机器上,但其中一个正在与互联网通信。另一个进程必须与该进程通信,以便在P2P网络上发送数据。 - Stephen Cross
啊哈,我还以为这个问题是关于如何建立P2P网络的。我甚至还没开始讲究洞穿和中继服务器之类的东西。 - Will

1

2
虽然在某些情况下UDP可能是不错的选择,但如果你想要数据完整无缺地传输,而且延迟并不是最重要的因素,那么TCP才是首选。 - Xorlev

0

虽然其他答案涵盖了部分问题(套接字库),但它们没有告诉您NAT问题。与其让用户调整其路由器,不如使用一些技术,这些技术应该可以在没有额外配置的情况下通过一个模糊的健全路由器。您需要使用所有这些技术以获得最佳兼容性。

首先,ICE library here 是一种NAT穿透技术,可与网络中的STUN和/或TURN服务器一起使用。为使其正常工作,您可能需要提供一些基础设施,尽管有一些公共STUN服务器可用。

其次,同时使用UPnP和NAT-PMP。例如,一个库here

第三,使用IPv6。Teredo是一种在IPv4上运行IPv6的方式,通常在以上方法均无法解决时起作用,而且谁知道,您的用户可能已经通过其他方式拥有了工作的IPv6。实现此功能所需的代码非常少,并且越来越重要。例如,我发现大约一半的Bittorrent数据通过IPv6到达。


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