ZeroMQ學習 (七) 多幀消息

9 多幀消息

​ ZMQ消息可以包含多個幀,這在實際應用中非常常見.

​ 多幀消息的每一幀都是一個zmq_msg結構,也就是說,當你在收發含有五個幀的消息時,你需要處理五個zmq_msg結構。你可以將這些幀放入一個數據結構中,或者直接一個個地處理它們。

下面的代碼演示如何發送多幀消息:

zmq_msg_send (&message, socket, ZMQ_SNDMORE);
...
zmq_msg_send (&message, socket, ZMQ_SNDMORE);
...
zmq_msg_send (&message, socket, 0);

然後我們看看如何接收並處理這些消息,這段代碼對單幀消息和多幀消息都適用:

while (1) 
{
    // 處理一幀消息
    zmq_msg_t message;
    zmq_msg_init (&message);
    zmq_msg_recv (&message, socket, 0);
    zmq_msg_close (&message);
  
    // 已到達最後一幀
    int64_t more;
    zmq_getsockopt (socket, ZMQ_RCVMORE, &more, sizeof (more));
    if (!more)
        break; 
}

關於多幀消息,你需要了解的還有:

  • 在發送多幀消息時,只有當最後一幀提交發送了,整個消息纔會被髮送;

  • 多幀消息是整體傳輸的,不會只收到一部分;

  • 多幀消息的每一幀都是一個zmq_msg結構;

  • 無論你是否檢查套接字的ZMQ_RCVMORE選項,你都會收到所有的消息;

  • 發送時,ZMQ會將開始的消息幀緩存在內存中,直到收到最後一幀纔會發送;

  • 我們無法在發送了一部分消息後取消發送,只能關閉該套接字。

還是發佈者:

//
//  Shows how to handle Ctrl-C
//
#include <zmq.h>
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
//  ---------------------------------------------------------------------
//  消息處理
//
//  程序開始運行時調用s_catch_signals()函數;
//  在循環中判斷s_interrupted是否爲1,是則跳出循環;

static int interrupted = 0;
void signal_handler (int sig)
{
    (void)sig;
    interrupted = 1;
}

void catch_signals (void)
{
    struct sigaction action;
    action.sa_handler = signal_handler;
    action.sa_flags = 0;
    sigemptyset (&action.sa_mask);
    sigaction (SIGINT, &action, NULL);
}

int main (void)
{
    catch_signals ();
    void *context = zmq_ctx_new();
    //  與客戶端通信的套接字
    void *publisher = zmq_socket (context, ZMQ_PUB);
    zmq_bind (publisher, "tcp://*:5555");
    //zmq_bind (publisher, "ipc:///tmp/myipc");
    char buf[256];
    int i = 0;
    while (1)
    {
        //每次發送兩幀
        zmq_send(publisher, "1000", 4, ZMQ_SNDMORE);
        sprintf(buf, "helloworld%d", i++);
        zmq_send (publisher, buf, strlen(buf),  0);
        sleep(1);
    }
    //  程序不會運行到這裏,以下只是演示我們應該如何結束
    zmq_close (publisher);
    zmq_ctx_destroy (context);
    return 0;
}

訂閱者一直收就好了


#include <zmq.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
void dump_msg(const void * data, int size)
{
    unsigned char * ptr = (unsigned char *)data;
    printf ("[%03d] ", size);
    int i = 0;
    for (i = 0; i < size; i++)
            printf ("%02X", ptr[i]);
    printf ("\n");
}

int main (void)
{
    void *context = zmq_ctx_new();
    void *subscriber = zmq_socket (context, ZMQ_SUB);
     /*訂閱1000的內容*/
    zmq_setsockopt(subscriber, ZMQ_SUBSCRIBE, "1000", 4);

  
    zmq_connect (subscriber, "tcp://127.0.0.1:5555");
    //zmq_connect (subscriber, "ipc:///tmp/myipc");
   
    while (1)
    {
        zmq_msg_t msg;
        zmq_msg_init(&msg);
        zmq_msg_recv (&msg, subscriber, 0);
        dump_msg(zmq_msg_data(&msg), zmq_msg_size(&msg));
        zmq_msg_close(&msg);
    }
    //  程序不會運行到這裏,以下只是演示我們應該如何結束
    zmq_close (subscriber);
    zmq_ctx_destroy(context);
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章