如何将数据序列化为C++ zmq 客户端和 Python zmq 服务器之间的通信
How to can I serialize data to Communication between C++ zmq client and Python zmq Server
>更新我的问题
如何在我的python zmq服务器中表示到达的消息以显示其内容?
根据这种行为,我可以假设btnState数据无论如何都会发送到python服务器吗?
上下文:
我正在发送一些数据成员结构 使用 C++ ZeroMQ 客户端进程:ZMQComponent.h
文件
#include <zmq.hpp>
#include <sofa/defaulttype/VecTypes.h>
// To Quat datatype
#include <sofa/defaulttype/Quat.h>
using sofa::defaulttype::Quat;
using std::string;
namespace sofa
{
namespace component
{
namespace controller
{
/* data structure which I want send data to python zmq server */
struct instrumentData
{
typedef sofa::defaulttype::Vec3d Vec3d;
Vec3d pos;
Quat quat;
int btnState;
float openInst;
bool blnDataReady;
};
class ZMQComponent : public sofa::core::behavior::BaseController
{
public:
SOFA_CLASS(ZMQComponent, sofa::core::behavior::BaseController);
ZMQComponent();
virtual ~ZMQComponent();
/* Conect to ZMQ external python Server */
void setupConnection();
/* Send some data memeber instrumentData structure to ZMQ external Server */
void instrumentDataSend(instrumentData a);
/* initialize function */
void init();
};
} // namespace sofa
} // namespace component
} // namespace controller
ZMQComponent.cpp
是:
#include <sofa/core/ObjectFactory.h>
#include <zmq.hpp>
#include <iostream>
#include <string>
#include "ZMQComponent.h"
using namespace std;
namespace sofa
{
namespace component
{
namespace controller
{
/* ZMQ Internal Client context and socket */
zmq::context_t context(1);
zmq::socket_t socket(context, ZMQ_REQ);
ZMQComponent::ZMQComponent(){}
void ZMQComponent::setupConnection()
{
cout << "Connecting to python zeroMQ server ..." << endl;
socket.connect("tcp://localhost:5555");
}
void ZMQComponent::instrumentDataSend(instrumentData a)
{
/* Initialize the data members structure instrumentData */
a.pos = sofa::defaulttype::Vec3d(1.0f, 1.0f, 1.0f);
a.quat = defaulttype::Quat(1.0f, 1.0f, 4.0f, 1.0f);
a.btnState = 5671;
a.openInst = 1.0f;
a.blnDataReady = false;
string s, test, result, d;
s = to_string(a.btnState);
test = " is a number";
result = s + test;
/* We send the btnState data */
zmq::message_t request(30);
/* We ask for the memory address to ge the btnState content and send it. */
memcpy(request.data(), &result, 30);
socket.send(request);
}
/* In the init function we create the objects to setup connection and send data */
void ZMQComponent::init()
{
std::cout << "ZeroMQCommunication::init()" << std::endl;
ZMQComponent z;
z.setupConnection();
instrumentData itemp;
z.instrumentDataSend(itemp);
}
/* Other code related .... */
ZMQComponent::~ZMQComponent(){}
// int ZeroMqComponentClass = sofa::core::RegisterObject("This component does nothing.").add<ZeroMqComponent>();
SOFA_DECL_CLASS(ZMQServerComponent)
int ZMQServerComponentClass = sofa::core::RegisterObject("This component create a Socket.").add< ZMQServerComponent >();
} // namespace controller
} // namespace component
} // namespace sofa
然后,我的python zmq服务器接收btnState
int变量是:
import time
import zmq
context = zmq.Context()
socket = context.socket(zmq.REP)
socket.bind("tcp://*:5555")
print('ZMQ Server listening ... ')
while True:
# Wait for next request from client
message = socket.recv()
print("Received message from Sofa: {}".format(message))
# Do some 'work'
time.sleep(1)
到达python zmq服务器的输出或消息是result
变量的内容(btnState
在s内容变量中变成字符串+字符串test
连接)和一些符号字符:
(cnvss_test) ➜ Python git:(ZMQCommunication) ✗ python server.py
ZMQ Server listening ...
Received message from Sofa: b'xb0x1dx19xf4xfdx7fx00x00x0ex00x00x00x00x00x00x0045 is a number'
我的 ZMQ python 服务器脚本上的先前输出显示,从沙发result
的字符串已到达服务器,并且它们的内容已可视化,但这些字符串或字符符号也是我的 C++ 客户端中定义的zmq::message_t request(30)
大小的产物或结果。
如果我在请求中分配小于 30 的值,例如zmq::message_t request(10)
服务器中的输出为:
Received message from Sofa: b'x90x94xa1x00xfcx7fx00x00x0ex00'
如果我在请求中分配一个大于 10 的值,例如zmq::message_t request(20)
我的服务器中的输出是:
Received message from Sofa: b'x80$(xc7xfcx7fx00x00x0ex00x00x00x00x00x00x0045 i
然后,我在服务器端收到的字符串或对象,它的长度或大小与分配给变量zmq::message_t request
一样长
基于上面提到的,ZMQ 是谁在我收到的消息中添加此字符串的?
根据前面的过程,我的消息到达我的服务器,那么正确的尝试是需要什么带有协议缓冲区之类的实体的序列化过程? 我知道使用像谷歌协议缓冲区这样的东西允许在发送的对象和接收的对象相对于其真实内容方面进行更严格的控制......
无论如何,如何删除到达服务器的消息中添加的字符串或字符符号?
任何支持或方向将不胜感激
您的系统是异构的,这意味着您需要某种与平台/语言无关的序列化。
就您的目的而言,最方便使用的一种可能是Google Protocol Buffers
.这很好地支持了C++和Python。有了这个,您将在模式文件中定义消息/数据结构(文件扩展名.proto
),并使用protoc
将其编译为C++源代码和Python源代码。这些类可以序列化/反序列化为同一连线格式/从同一连线格式反序列化。序列化/反序列化可以很好地与 ZMQ 消息缓冲区集成。
还有其他的;
Apache Avro
是可能的。- 我会避免
XSD
模式;原则上它们很好,但找到真正完成正确和完整工作的代码生成器是困难/昂贵的。例如,xsd.exe
(来自Microsoft)可以编译 XSD 架构以C++类(我认为),但忽略架构中的约束字段(例如。MinInclusive
)。 - ASN1真的很好,但我还没有找到一个像样的Python实现。有一个用于python(pyasn)的ASN.1的代码优先实现,但这忽略了拥有ASN.1模式的全部意义......
我在 c++ 中使用了类似的 zmq 实现和沙发框架(与 autor 插件相关)。
将数据从 zmq C++发送到 python zmq 没有任何问题。
以下是我用python编写的zmq服务器的概述:
import zmq
context = zmq.Context()
socket = context.socket(zmq.SUB)
socket.setsockopt(zmq.SUBSCRIBE, "")
print "Collecting data from c++ ..."
socket.connect ("tcp://127.0.0.1:6000")
while True:
print socket.recv()
以下是结果的概述:
douaille@douaille:~/Documents/zmq$ python zmqClient.py
Collecting data from c++ ...
/colorLight string:'1 1 1 1'
/colorLight string:'1 1 1 1'
/colorLight string:'1 1 1 1'
/colorLight string:'1 1 1 1'
/colorLight string:'1 1 1 1'
/colorLight string:'1 1 1 1'
我正在使用 zmq 作为发布者,但它不会根据您的需求更改任何内容。另外,请求客户端的实现几乎相同。 看起来您正在打印请求而不是消息
你可以在这里找到 c++ 发送器部分的实现: https://github.com/SofaDefrost/sofa/blob/sofaCommunication/applications/plugins/Communication/components/serverCommunicationZMQ.inl
编辑:
下面是一个使用 zmq 请求的示例:
import zmq
context = zmq.Context()
socket = context.socket(zmq.REQ)
print("Collecting data from c++ using REQ ...")
socket.connect("tcp://localhost:6000")
while True:
print("Sending request")
socket.send(b"Hello")
message = socket.recv()
print("Received reply : %s" % message)
结果:
douaille@douaille:~/Documents/zmq$ python zmqClient.py
Collecting data from c++ using REQ ...
Sending request
Received reply : /colorLight string:'1 1 1 1'
Sending request
Received reply : /colorLight string:'1 1 1 1'
Sending request
Received reply : /colorLight string:'1 1 1 1'
- 如何运行位于boost/libs/python/example/tutorial目录中的hello.cpp和Jamfil
- Pybind11:将元组列表从Python传递到C++
- 如何在c++中使用引用实现类似python的行为
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 递归列出所有目录中的C++与Python与Ruby的性能
- IPC使用多个管道和分支进程来运行Python程序
- 从python中调用C++函数并获取返回值
- Python 3.7 和 excess_args 的 SWIG 问题
- Python中的for循环与C++有何不同
- 使用Pybind11向Python公开Eigen::张量
- Python str to C++ to Python str
- 如何使用Python从C++中读取谷物序列化数据
- 如何在C++中使用pybind11加载一个pickle python列表
- 如何将数据序列化为C++ zmq 客户端和 Python zmq 服务器之间的通信
- ZMQ Python PUB/SUB 有效,但我的 C++ Subscriber with Python Publish
- ZMQ Python发布C 订阅
- 使用C++客户端 - Python 服务器通过 Zmq 发送 JSON 对象
- 如何使用zmq/zeromq从传递给python的字符串表示(字节数组)中获取整数/浮点数
- Zeromq (zmq)与c++发布者和python订阅者丢失消息
- 如何启动python内核并使用ZMQ套接字进行连接