You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Msgpack反序列化报错msgpack::v1::insufficient_bytes求助

问题描述

发布端通过ZeroMQ库发送经Msgpack打包的字符串消息,运行状态正常,可正常发送消息。订阅端接收数据时编译无报错,但运行至代码行msgpack::unpack(msg, static_cast<const char*>(got.data()), got.size());时程序中断,抛出错误msgpack::v1::insufficient_bytes。

发布端代码

#include <future>
#include <iostream>
#include <string>
#include <thread>

#include "zmq.hpp"
#include "zmq_addon.hpp"
#include<msgpack.hpp>

int main()
{
    zmq::context_t ctx(1);
    zmq::socket_t publisher(ctx, zmq::socket_type::pub);

    std::stringstream ss;
    
    publisher.bind("tcp://127.0.0.1:5041");
    
    std::this_thread::sleep_for(std::chrono::milliseconds(500));
    std::string msg_str = "Test";

    msgpack::sbuffer sbuf;

    
    msgpack::pack(sbuf, msg_str);

    zmq::message_t msg_send(sbuf.size());
    memcpy(msg_send.data(), sbuf.data(), sizeof(sbuf));
    
    
    while (true)
    {

        publisher.send(msg_send, zmq::send_flags::none);
        std::cout << "Mitteilung ist online: " << std::endl;
        std::this_thread::sleep_for(std::chrono::milliseconds(500));
        
    }

}

订阅端代码

#include <iostream>
#include<zmq.h>
#include<zmq.hpp>
#include<msgpack.hpp>
#include<vector>
#include<string>
#include <thread>

int main()
{
    zmq::context_t ctx(1);
    zmq::socket_t subscriber(ctx, zmq::socket_type::sub);

    subscriber.connect("tcp://127.0.0.1:5041");

    subscriber.set(zmq::sockopt::subscribe, "");
    
    while (1)
    {
        std::string um_str_;
        msgpack::unpacked msg;
        zmq::message_t got;
       
        subscriber.recv(got);
        msgpack::object obj = msg.get();

        std::cout << "Hier" << std::endl;

        msgpack::unpack(msg, static_cast<const char*>(got.data()), got.size());
       // obj.convert(um_str_);

    }

}
问题原因及解决方案

1. 发布端的数据拷贝错误

发布端中memcpy(msg_send.data(), sbuf.data(), sizeof(sbuf));存在致命错误:sizeof(sbuf)获取的是msgpack::sbuffer对象本身的内存大小,而非它实际存储的Msgpack打包数据的字节长度。这导致发送的消息长度远小于真实的打包数据长度,订阅端收到不完整的数据后,解包时就会触发insufficient_bytes错误。

修正方式:将sizeof(sbuf)替换为sbuf.size(),确保拷贝完整的打包数据:

memcpy(msg_send.data(), sbuf.data(), sbuf.size());

2. 订阅端的代码执行顺序错误

订阅端中msgpack::object obj = msg.get();在msgpack::unpack之前调用,此时msgpack::unpacked msg还未被初始化,调用msg.get()会导致未定义行为,同时打乱了解包的正常流程。

修正方式:调整代码顺序,先执行解包操作,再获取msgpack::object并转换数据:
修正后的订阅端循环部分代码:

while (1)
{
    std::string um_str_;
    msgpack::unpacked msg;
    zmq::message_t got;
   
    subscriber.recv(got);
    std::cout << "Hier" << std::endl;

    // 先执行解包
    msgpack::unpack(msg, static_cast<const char*>(got.data()), got.size());
    msgpack::object obj = msg.get();
    // 转换数据
    obj.convert(um_str_);
    std::cout << "解析到消息:" << um_str_ << std::endl;
}
修正后的完整代码

发布端完整代码

#include <future>
#include <iostream>
#include <string>
#include <thread>

#include "zmq.hpp"
#include "zmq_addon.hpp"
#include<msgpack.hpp>

int main()
{
    zmq::context_t ctx(1);
    zmq::socket_t publisher(ctx, zmq::socket_type::pub);

    std::stringstream ss;
    
    publisher.bind("tcp://127.0.0.1:5041");
    
    std::this_thread::sleep_for(std::chrono::milliseconds(500));
    std::string msg_str = "Test";

    msgpack::sbuffer sbuf;
    msgpack::pack(sbuf, msg_str);

    zmq::message_t msg_send(sbuf.size());
    memcpy(msg_send.data(), sbuf.data(), sbuf.size());
    
    while (true)
    {
        publisher.send(msg_send, zmq::send_flags::none);
        std::cout << "消息已发送" << std::endl;
        std::this_thread::sleep_for(std::chrono::milliseconds(500));
    }
}

订阅端完整代码

#include <iostream>
#include<zmq.h>
#include<zmq.hpp>
#include<msgpack.hpp>
#include<vector>
#include<string>
#include <thread>

int main()
{
    zmq::context_t ctx(1);
    zmq::socket_t subscriber(ctx, zmq::socket_type::sub);

    subscriber.connect("tcp://127.0.0.1:5041");
    subscriber.set(zmq::sockopt::subscribe, "");
    
    while (1)
    {
        std::string um_str_;
        msgpack::unpacked msg;
        zmq::message_t got;
       
        subscriber.recv(got);
        std::cout << "收到原始数据" << std::endl;

        msgpack::unpack(msg, static_cast<const char*>(got.data()), got.size());
        msgpack::object obj = msg.get();
        obj.convert(um_str_);

        std::cout << "解析后消息:" << um_str_ << std::endl;
    }
}

内容的提问来源于stack exchange,提问作者Trixxx128

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 03:21:11