通过tcp接收编码图像的接收消息时,zmq在第二个循环中崩溃

时间:2018-08-03 09:34:38

标签: c++ zeromq

在以下使用zmq和opencv编码和解码的示例中,服务器在显示接收到的第一张图像后,在recv()函数中崩溃。我想知道是否有人知道代码崩溃的原因。

崩溃消息是“ C ++异常:内存位置处的zmq :: error_t”。

服务器

#include <zmq.hpp>
#include <string.h>
#include <stdio.h>
#include <opencv2/opencv.hpp>
#include "fstream"
#include "iostream"
int main()
{
    //  Prepare our context and socket
    zmq::context_t context(1);
    zmq::socket_t socket(context, ZMQ_REP);
    socket.bind("tcp://*:6666");
    while (true)
    {
        //  receive message
        std::string msgStr;
        {
            zmq::message_t message;
            socket.recv(&message);
            msgStr = std::string((char*)message.data(), message.size());
        }
        //  unserialize to cv::mat
        cv::Mat loaded_data;
        {
            std::vector<uchar> data(msgStr.begin(), msgStr.end());
            loaded_data = cv::imdecode(data, CV_LOAD_IMAGE_GRAYSCALE);
        }
        //  show cv::mat
        {
            std::cout << "waiting for your key press on the image." << "\n";
            cv::imshow("load", loaded_data);
            cv::waitKey(0);
        }
    }
    socket.close();
    return 0;
}

客户端

#include <stdio.h>
#include <opencv2/opencv.hpp>
#include "fstream"
#include "iostream"
int main()
{
    zmq::context_t context(1);
    zmq::socket_t sock(context, ZMQ_REQ);
    sock.connect("tcp://localhost:6666");
    std::string data;
    {
        cv::Mat Imgdata = cv::imread("wall.jpg", CV_LOAD_IMAGE_GRAYSCALE);
        std::vector<uchar> data_encode;
        cv::imencode(".jpg", Imgdata, data_encode);
        data = std::string(data_encode.begin(), data_encode.end());
    }
    // send
    {
        zmq::message_t message(data.size());
        memcpy(message.data(), data.c_str(), data.size());
        sock.send(message);
    }
    sock.close();
    system("pause");
    return 0;
}

1 个答案:

答案 0 :(得分:2)

不要忽略recv函数的返回。 进行if(socket.recv(...)) { // Process image }可以避免在接收过程中出错时执行代码。

您正在使用REQ / REP套接字。 这是一个同步协议。 REQ最初可以发送一条消息,并且只要没有对请求的答复,就会被阻止。 REP最初可以接收到一条消息,并且只要他们没有回答请求,就会被屏蔽。

在收到第一个图像后回复REQ套接字,或使用其他模式:ZMQ_PAIR,PUSH / PULL,ROUTER / DEALER均可在您的情况下工作。 Read the documentation to learn about the different pattern

此外,您不必将图像转换为字符串。您可以使用zmq直接发送std::vector<uint8_t>:您可以使用std::vector::data()memcpy(message.data(), vector.data(), vector.size())访问基础指针。