当通过 tcp 接收编码图像的消息时,zmq 在第二个循环中崩溃
zmq crash in the second loop when recv message of an encoded image through tcp
在以下使用 zmq 和 opencv 编码和解码的示例中,服务器在 recv() 函数显示接收到的第一张图像后崩溃。我想知道有没有人知道代码崩溃的原因
崩溃信息是"C++ exception: zmq::error_t at memory location."
服务器
#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;
}
不要忽视recv函数的return。
执行 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())
.
访问底层指针
在以下使用 zmq 和 opencv 编码和解码的示例中,服务器在 recv() 函数显示接收到的第一张图像后崩溃。我想知道有没有人知道代码崩溃的原因
崩溃信息是"C++ exception: zmq::error_t at memory location."
服务器
#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;
}
不要忽视recv函数的return。
执行 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())
.