Можете ли вы вызвать zmq_recv с буфером NULL и длиной 0, чтобы пропустить сообщение?

Я использую zmq (3.2) и использую составные сообщения. Я обрабатываю некоторые случаи ошибок, когда первая часть сообщения недействительна, и я хочу отбросить оставшиеся части. То, о чем я думал, было чем-то вроде.

void zmq_drain_multipart(void *sock)
{
    int more;
    size_t size = sizeof(int);
    zmq_getsockopt(sock, ZMQ_RCVMORE, &more, &size);
    while (more)
    {
        zmq_recv(sock, NULL, 0, 0);
        zmq_getsockopt(sock, ZMQ_RCVMORE, &more, &size);
    }
}

Что-то вроде этого должно работать.


person Matt    schedule 03.12.2013    source источник
comment
Ты это пробовал? Что случилось?   -  person Some programmer dude    schedule 03.12.2013
comment
Работает это или нет, это не то, что я хочу знать. Я хочу знать, ДОЛЖНО ли это работать, а не просто работать. Я не хочу вводить какой-либо код, который мог бы работать сейчас, но ломается с обновлениями zmq.   -  person Matt    schedule 03.12.2013
comment
Да, вроде работает.   -  person Matt    schedule 03.12.2013


Ответы (2)


ИМО, окончательным авторитетом в отношении правильности является страница API по адресу http://api.zeromq.org/3-2:zmq-recv. Несмотря на то, что ваш код работает — и, вероятно, продолжит работу с новыми версиями ZeroMQ — вы не следуете правилам.

Аргумент 2 (buf) — это ссылка на буфер. Нет упоминания о каком-либо особом случае, когда вы можете указать NULL. К счастью, если полученная полезная нагрузка больше аргумента 3 (len), данные будут усечены. Это означает, что вы можете предоставить действительно небольшой буфер. Он может быть основан на стеке, чтобы избежать затрат на выделение памяти, как показано ниже.

void zmq_drain_multipart(void *sock)
{
    int more;
    size_t size = sizeof(int);
    zmq_getsockopt(sock, ZMQ_RCVMORE, &more, &size);
    while (more)
    {
        char buf[32];
        zmq_recv(sock, buf, 32, 0);
        zmq_getsockopt(sock, ZMQ_RCVMORE, &more, &size);
    }
}

Это также имеет небольшое преимущество, когда что-то идет не так. При выполнении отладчика приведенный выше код позволит вам проверить первые несколько байтов каждого получаемого и удаляемого фрагмента.

person Guido Simone    schedule 04.12.2013
comment
Спасибо, я так и думал. Я не хочу полагаться на поведение, которое само собой срабатывает. - person Matt; 08.12.2013
comment
Я могу понять небольшое беспокойство по поводу передачи NULL, но вы, кажется, рекомендуете полностью не использовать 0 length. Есть ли что-то в документации API или другом исходном коде, что подталкивает вас в этом направлении? У меня похожая ситуация с полным буфером, который я мог бы просто продолжать использовать с 0 len, если позже это не будет проблемой. Также кажется, что чтение ничего не должно быть более быстрой операцией, чем чтение даже 1 байта. - person ebyrob; 07.11.2017

В ZMQ 4.3 вы можете сделать это официально: «Аргумент buf может быть нулевым, если len равен нулю». http://api.zeromq.org/4-3:zmq-recv

person grzegorz    schedule 18.06.2020