简体   繁体   中英

How to separate message zmq server?

I am trying to send a video through a ZeroMQ server and I successfully got it with a 1 GB video, but when I try to send a movie with, with a very larger size ( 6.7 GB ) I get the following error:

cliente: /usr/local/include/zmq.hpp:1958: zmq::recv_result_t zmq::detail::socket_base::recv(zmq::message_t&, zmq::recv_flags): Assertion `msg.size() == static_cast<size_t>(nbytes)' failed.
make: *** [Makefile:7: cliente] Aborted
make: *** Deleting file 'cliente'

So I tried to break the file on the server and send it separately to the client, but I got the same error. Does someone know how to separate the message_t to send it separately to the client?
This is the server code:

#include <fstream>
#include <sstream>
#include <chrono>
#include <thread>
#include <iostream>
#include <zmq.hpp>

using namespace std::chrono_literals;

int main()
{
  zmq::context_t context(1);
  zmq::socket_t socket(context, zmq::socket_type::rep);
  socket.bind("tcp://*:5555");
  std::ifstream img("video.mkv", std::ifstream::in | std::ios::binary);
  for (;;)
  {
    zmq::message_t message;
    socket.recv(message, zmq::recv_flags::none);
    std::ostringstream os;
    os << img.rdbuf();
    std::string oss(os.str());
    socket.send(zmq::buffer(oss.substr(0, (oss.size() / 2))), zmq::send_flags::sndmore);
    std::this_thread::sleep_for(1s);
    socket.send(zmq::buffer(oss.substr((oss.size() / 2), oss.size() - 1)), zmq::send_flags::none);
    std::this_thread::sleep_for(1s);
  }
}

This is my client:

#include <fstream>
#include <sstream>
#include <iostream>
#include <string>
#include <zmq.hpp>

int main()
{
  std::ofstream img("teste.mkv", std::ios::out | std::ios::binary);
  zmq::context_t context(2);
  zmq::socket_t socket(context, zmq::socket_type::req);
  socket.connect("tcp://localhost:5555");
  zmq::message_t message_1, message_2;
  socket.send(zmq::buffer("ok\n"), zmq::send_flags::none);
  socket.recv(message_1, zmq::recv_flags::none);
  std::string data_1(message_1.to_string());
  img << data_1;
  data_1.clear();
  socket.recv(message_2, zmq::recv_flags::none);
  std::string data_2(message_2.to_string());
  img << data_2;
  data_2.clear();
}

Q : "How to separate message zmq server?"

Well, avoid attempts to move 6.7 GB at once. Doing a sndmore -trick to send that huge volume of data as a multi-part structured message does not save the problem, as such a structured message will (almost) never fit into RAM-constraints.

Best setup an indexing data-reader, move the huge data-file in reasonably sized solo-blocks ( avoid using a multi-part kind of messages ) and make the receiver keep track of what index-numbers have been received so far ( confirming POSACK'd receptions to the sender + re-requesting missing index-blocks to get ev. resent ).

ZeroMQ does not provide warranty of delivering any message, yet it makes you sure, that if you have .recv() -ed a payload, it is a binary-identical replica of the .send() -dispatched data. So, prepend an index-number and send payloads as described & you have a reasonably robust BLOB-parse/send/re-assemble with a few possible re-send requests.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM