零拷贝接收和消息大小

时间:2016-09-28 15:52:22

标签: zeromq

当使用零拷贝进行接收时,有没有办法查询收到的消息的大小?

这样我(尝试)实现零拷贝:

zmq_recv(sock, buf, sizeof(buf), 0);

我也尝试过:

zmq_msg_t msg;
zmq_msg_init_data (&msg, buf, sizeof(buf), nullptr, NULL);
zmq_msg_recv(&msg, sock, 0);
size_t len = zmq_msg_size(&msg);

这会返回正确的大小,但不会填充buf。我认为zmq_msg_init_data不适合与zmq_msg_recv一起使用,并且会在接收时重建消息。

2 个答案:

答案 0 :(得分:5)

在零拷贝上引用guide

  

接收时无法进行零拷贝:ZeroMQ为您提供了一个可以存储的缓冲区,只要您愿意,它就不会直接将数据写入应用程序缓冲区。

零拷贝仅用于发送,不用于接收。

哦,zmq_recv 返回收到的字节数。

答案 1 :(得分:0)

如果您使用JeroMQ(Pure Java for ZeroMQ),您可以通过ZMQ.Socket.setMsgAllocator实现接收方的零拷贝

通常来说,我们只关心大对象的零拷贝,因此您可以设置自定义消息分配器 例如:

/

原生C ++代码:

class MappedMemoryMsgAllocator implements MsgAllocator {

static final MsgAllocatorHeap heap = new MsgAllocatorHeap();
private final int threshold;

public MappedMemoryMsgAllocator(int threshold) {
    this.threshold = threshold;
}

public MappedMemoryMsgAllocator() {
    this(1024 * 1024 * 4);
}

@Override
public Msg allocate(int size) {
    if ((threshold > 0) && (size > threshold)) {
        try {
            return new Msg(UtilsJNI.nativeMapMemory(size, UtilsJNI.PROT_WRITE, UtilsJNI.MAP_PRIVATE));
        } catch (IOException e) {
            Log.d(TAG, "allocate:: fail to mmap", e);
            return null;
        }
    } else {
        return heap.allocate(size);
    }
}

public static void forceFreeMsgArray(zmq.Msg[] msgs) {
    if (msgs != null) {
        for (zmq.Msg msg : msgs) {
            final ByteBuffer buf = msg.buf();
            if (buf.isDirect()) {
                try {
                    UtilsJNI.nativeUnmapMemory(buf);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}