将 "zmq_send" 命令迁移到 Python

Migrate a "zmq_send" command to Python

我有一个将数据发布到 c++ 订阅者的 c 函数,现在我想将这个 c 函数迁移到 Python:

void setup_msg_publish() {
    int r;
    zmqcontext = zmq_ctx_new();
    datasocket = zmq_socket(zmqcontext, ZMQ_PUB);
    r = zmq_bind(datasocket, "tcp://*:44000");
    if (r == -1) {
        printf(zmq_strerror(errno));
    }
}
void publishdata(int x, int y) {
    if (datasocket == 0) {
        setup_msg_publish();
    }
    zmq_data zd;
    zd.msgType = int 0;
    zd.x = x;
    zd.y = y;
    size_t len = sizeof(zd);
    int res = zmq_send(datasocket, &zd, len, NULL);
    assert(res == len);
}

我已经尝试在 Python 中实现它:

import zmq
import pickle
from collections import namedtuple
Data = namedtuple("Data", "msgType x y")
def send_zmq():
    data = Data("0", "1", "2")
    msg = pickle.dumps(data)  

    context = zmq.Context()
    socket = context.socket(zmq.REQ)
    socket.connect("tcp://127.0.0.1:44000")
    socket.send(msg)

出于调试目的,我可以像这样使用 Python 接收数据:

import zmq
import pickle
context = zmq.Context()

socket = context.socket(zmq.REP)
socket.bind("tcp://127.0.0.1:44000")

while True:
    message = socket.recv()
    data = pickle.loads(message)
    print(data)

但我的 C++ 代码没有收到任何信息(它只打印 no data):

#include "View.h"
#include <iostream>
#include <thread>
#include <chrono>

View::View() :
    viewSubscriber(zmqcontext, ZMQ_SUB)
{
    unsigned _int16 msgType = 0;
    viewSubscriber.connect("tcp://127.0.0.1:44000");
    //viewSubscriber.setsockopt(ZMQ_SUBSCRIBE, &msgType, sizeof(msgType));
    viewSubscriber.setsockopt(ZMQ_SUBSCRIBE, "", 0);
    std::cout << msgType;
}

void View::run() {
    using namespace std;
    bool received_view_data = false;

    bool checkForMore = true;
    zmq_view data;
    while (checkForMore) {
        zmq::message_t msg;
        //cout << &msg;
        if (viewSubscriber.recv(&msg, ZMQ_NOBLOCK)) {
            received_view_data = true;
            memcpy(&data, msg.data(), sizeof(data));
            cout << &data.x;
        }
        else {
            std::this_thread::sleep_for(std::chrono::milliseconds(500));
            cout << "no data \n"; 
        }
    }
}

int main(){
    View *app = new View();
    app -> run();
    return 0;
}

知道要修复什么以便我在 c++ 端的 namedTuple 中接收数据吗?难道是 C++“需要了解更多”关于 namedTuple 的每个属性的类型(如果是这种情况,我如何指定数据是 double 还是 int 等?)?

从 C++ 测试后找到了解决方案 -> Python 谢谢 J_H 的想法。没有使用 namedtuple,而是使用了打包结构。

import zmq
import struct
def send_zmq():
    struct_format = 'Idd'
    msg_type = 0
    x = 1.0
    y = 1.0
    msg = struct.pack(struct_format, msg_type, x, y)
    context = zmq.Context()
    socket = context.socket(zmq.REQ)
    socket.connect("tcp://127.0.0.1:44000")
    socket.send(msg)