我需要使用内置C ++类型的参数从客户端进程向服务器进程发送(可能是一个)简单的单向命令(因此序列化非常简单)。 C ++,Windows XP +。
我正在寻找一个不需要复杂配置的库,提供简单的界面,不需要数小时的学习时间,也没有商业使用限制。解决简单问题的简单方法。
Boost.Interprocess对于这个简单的任务来说太低级了,因为它不提供RPC接口。套接字也可能是一种过度杀伤,因为我不需要在机器之间进行通信。关于DCOM,CORBA等人也是如此。命名管道?从未使用过它们,WinAPI上的任何好库?的openmpi?
答案 0 :(得分:17)
我不认为套接字真的有点过分。替代方案都有自己的问题,并且套接字比命名管道,共享内存等更好地支持,因为几乎每个人都在使用它们。本地系统上的套接字速度可能不是问题。
有Apache Thrift:
http://incubator.apache.org/thrift/
有一些RPC实现包含在Google的protobuf库中作为编组机制:
https://github.com/google/protobuf/blob/master/docs/third_party.md#rpc-implementations
有XML-RPC:
http://xmlrpc-c.sourceforge.net/
如果您的消息真的简单,我可能会考虑使用UDP数据包,然后没有可以管理的连接。
答案 1 :(得分:9)
您可能希望ZeroMQ获得此类内容。也许不是一个完整的RPC,可以用作生成RPC的原始字节消息传递框架。它简单,轻便,性能出众。您可以轻松地在其上实现RPC。以下是手册中的示例服务器:
//
// Hello World server in C++
// Binds REP socket to tcp://*:5555
// Expects "Hello" from client, replies with "World"
//
#include <zmq.hpp>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int main () {
// Prepare our context and socket
zmq::context_t context (1);
zmq::socket_t socket (context, ZMQ_REP);
socket.bind ("tcp://*:5555");
while (true) {
zmq::message_t request;
// Wait for next request from client
socket.recv (&request);
printf ("Received Hello");
// Do some 'work'
sleep (1);
// Send reply back to client
zmq::message_t reply (5);
memcpy ((void *) reply.data (), "World", 5);
socket.send (reply);
}
return 0;
}
此示例使用tcp://*.5555,但如果使用:
,则使用更有效的IPC技术socket.bind("ipc://route.to.ipc");
甚至更快的线程间协议:
socket.bind("inproc://path.for.client.to.connect");
答案 2 :(得分:6)
如果您只需要支持Windows我会使用Windows内置RPC,我已经写过两篇关于此的介绍性文章:
http://www.codeproject.com/KB/IP/rpcintro1.aspx
http://www.codeproject.com/KB/IP/rpcintro2.aspx
如果您只需要本地进程间通信,则可以使用ncalrpc
协议。
答案 3 :(得分:5)
Boost.MPI。简单,快速,可扩展。
#include <boost/mpi/environment.hpp>
#include <boost/mpi/communicator.hpp>
#include <iostream>
#include <sstream>
namespace mpi = boost::mpi;
int main(int argc, char* argv[])
{
mpi::environment env(argc, argv);
mpi::communicator world;
std::stringstream ss;
ss << "Hello, I am process " << world.rank() << " of " << world.size() << ".";
world.send(1, 0, ss.str());
}
答案 4 :(得分:3)
如果您只在Windows上工作,并且确实需要C ++接口,请使用COM / DCOM。它基于RPC(依次基于DCE RPC)。
使用极其简单 - 只要您花时间学习基础知识。
答案 5 :(得分:2)
你可能甚至不需要图书馆。 Windows在其核心API(windows.h)中深入构建了IPC机制。您基本上可以将Windows消息发布到不同进程主窗口的消息队列中。 Windows甚至定义了一个标准消息:WM_COPYDATA。
发送过程基本上是这样做的:
接收过程(窗口):
答案 6 :(得分:2)
我知道我们远离易用性。但当然你可以坚持使用CORBA。例如。 ACE/TAO
答案 7 :(得分:1)
我告诉RPC Raknet很简单。
答案 8 :(得分:1)
另外,您可以查看msgpack-rpc
更新
虽然Thrift / Protobuf更灵活,但我认为,但需要以特定格式编写一些代码。例如,Protobuf需要一些.proto文件,它可以使用包中的特定编译器进行编译,从而生成一些类。在某些情况下,代码的其他部分可能更难。 msgpack-rpc要简单得多。它不需要写一些额外的代码。这是一个例子:
#include <iostream>
#include <msgpack/rpc/server.h>
#include <msgpack/rpc/client.h>
class Server: public msgpack::rpc::dispatcher {
public:
typedef msgpack::rpc::request request_;
Server() {};
virtual ~Server() {};
void dispatch(request_ req)
try {
std::string method;
req.method().convert(&method);
if (method == "id") {
id(req);
} else if (method == "name") {
name(req);
} else if (method == "err") {
msgpack::type::tuple<> params;
req.params().convert(¶ms);
err(req);
} else {
req.error(msgpack::rpc::NO_METHOD_ERROR);
}
}
catch (msgpack::type_error& e) {
req.error(msgpack::rpc::ARGUMENT_ERROR);
return;
}
catch (std::exception& e) {
req.error(std::string(e.what()));
return;
}
void id(request_ req) {
req.result(1);
}
void name(request_ req) {
req.result(std::string("name"));
}
void err(request_ req) {
req.error(std::string("always fail"));
}
};
int main() {
// { run RPC server
msgpack::rpc::server server;
std::auto_ptr<msgpack::rpc::dispatcher> dispatcher(new Server);
server.serve(dispatcher.get());
server.listen("0.0.0.0", 18811);
server.start(1);
// }
msgpack::rpc::client c("127.0.0.1", 18811);
int64_t id = c.call("id").get<int64_t>();
std::string name = c.call("name").get<std::string>();
std::cout << "ID: " << id << std::endl;
std::cout << "name: " << name << std::endl;
return 0;
}
输出
ID: 1
name: name
您可以在此处找到更复杂的示例https://github.com/msgpack/msgpack-rpc/tree/master/cpp/test
答案 9 :(得分:0)
我正在使用XmlRpc C ++ for Windows found here
真的很容易使用:)但唯一的副作用是只是一个客户端!
答案 10 :(得分:0)
还有Microsoft Messaging Queueing,当所有进程都在本地计算机上时,使用起来非常简单。
答案 11 :(得分:-3)
进程间通信最简单的解决方案是使用文件系统。请求和响应可以写为临时文件。您可以为请求和响应文件制定命名约定。
这不会给你最好的表现,但也许它会足够好。