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
//
// ---------------------------------------------------------------------
// 消息處理
//
// 程序開始運行時調用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;
}
訂閱者一直收就好了
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; }