如何将数据序列化到C++ ZMQ客户端和Python ZMQ之间的通信

2024-09-25 00:32:27 发布

您现在位置:Python中文网/ 问答频道 /正文

更新我的问题

如何在pythonzmq服务器中表示到达的消息以显示它们的内容?在

根据这种行为,我可以假设btnState数据无论如何都被发送到python服务器吗?在

上下文:

我正在发送一些数据成员结构 使用C++零卷客户端进程: 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是:

^{pr2}$

然后,接收btnStateint变量的pythonzmq服务器是:

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 content变量中的字符串+串接的字符串test)和一些符号字符:

(cnvss_test) ➜  Python git:(ZMQCommunication) ✗ python server.py
ZMQ Server listening ...
Received message from Sofa: b'\xb0\x1d\x19\xf4\xfd\x7f\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x0045 is a number'

我的ZMQ Python服务器脚本上的前一个输出显示了从沙发上的字符串{{CD4}}到达服务器,它们的内容是可视化的,但是,这个字符串或字符符号,是产品在我的C++客户端中定义的初始大小或结果的结果。在

如果我在请求中分配一个小于30的值,例如zmq::message_t request(10)我的服务器中的输出是:

Received message from Sofa: b'\x90\x94\xa1\x00\xfc\x7f\x00\x00\x0e\x00'

如果我在请求中分配了一个大于10的值,例如zmq::message_t request(20)我的服务器中的输出是:

Received message from Sofa: b'\x80$(\xc7\xfc\x7f\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x0045 i

那么,我在服务器端接收到的字符串或对象,其长度或大小与分配给zmq::message_t request变量的长度或大小相同

基于以上提到的,ZMQ是谁在我收到的消息中添加这个字符串的?在

根据前面的过程,我的消息到达我的服务器,那么正确的尝试是什么样的序列化过程与一些实体如协议缓冲区是必要的? 我知道,使用类似google协议缓冲区这样的东西,可以对发送的对象和接收到的对象的真实内容进行更多的控制。。。在

在任何情况下,我如何删除在到达服务器的消息中添加的字符串或字符符号?在

任何支持或指导将不胜感激


Tags: 字符串from服务器消息内容messageserverzmq
2条回答

我在sofa框架中使用类似的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()

以下是结果概述:

^{pr2}$

我使用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' 

您的系统是异构的,这意味着您需要某种与平台/语言无关的序列化。在

出于您的目的,最方便使用的可能是Google Protocol Buffers。这非常支持C++和Python。这样,您将在模式文件(文件扩展名^ {CD2}})中定义消息/数据结构,并使用^ {CD3}}将其编译为C++源代码和Python源代码。这些提供了可以序列化/反序列化到同一wireformat的类。序列化/反序列化可以很好地与ZMQ消息缓冲区集成。在

还有其他的

  • Apache Avro是可能的。在
  • 我会避免使用XSD模式;原则上,它们很好,但是要找到真正完成正确完整工作的代码生成器是困难的/昂贵的。例如,^ {< CD6> }(来自微软)可以编译XSD模式到C++类(我想),但是忽略了架构中的约束字段(E.D^ { CD7}})。在
  • ASN1确实很好,但是我还没有找到一个适合Python的实现。ASN.1forpython(pyasn)有一个代码优先的实现,但这忽略了ASN.1模式的全部意义。。。在

相关问题 更多 >