ZMQ_ROUTER類型的套接字是請求/回覆模式的一種升級。
當ZMQ_ROUTER收到一個消息的時候,會自動在消息前面添加一幀,這一幀用來識別發送端的地址。
當發送一個消息的時候,需要先發送一幀對端的地址,然後再發送消息,如果目的地址指向的對端不存在了,這個消息就會被丟棄。
對端的地址默認情況下由ZMQ來產生一個唯一標識UUID。
ROUTER源碼:
//
// Shows how to handle Ctrl-C
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 *router = zmq_socket (context, ZMQ_ROUTER);
zmq_bind (router, "tcp://*:5555");
int ret;
zmq_msg_t address;
zmq_msg_t data;
while (1)
{
zmq_msg_init(&address);
zmq_msg_init(&data);
/*接收到的第一幀表示對端的地址*/
ret = zmq_msg_recv (&address, router, 0);
dump_msg(zmq_msg_data(&address), ret);
/*從第二幀開始纔是對端發來的消息*/
ret = zmq_msg_recv (&data, router, 0);
dump_msg(zmq_msg_data(&data), ret);
/*發送的時候,先發一幀對端的地址*/
zmq_msg_send(&address, router, ZMQ_SNDMORE);
/*然後再發送給對端消息*/
memcpy(zmq_msg_data(&data), "world", strlen("world"));
zmq_msg_send(&data, router, 0);
zmq_msg_close(&address);
zmq_msg_close(&data);
}
zmq_close (router);
zmq_ctx_destroy (context);
return 0;
}
DEALER可以任意讀寫,不需要額外的地址幀,當有多個對端的時候,循環給單個對端發送消息。(注意:不是羣發消息,與PUB不同)。
DEALER源碼:
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 *dealer = zmq_socket (context, ZMQ_DEALER);
zmq_connect (dealer, "tcp://127.0.0.1:5555");
int ret;
char buf[256] = "hello";
while (1)
{
/*發送一幀,不需要發送地址幀*/
zmq_send (dealer, buf, strlen(buf), 0);
sleep(1);
/*接收一幀,不會接收到地址幀*/
ret = zmq_recv (dealer, buf, sizeof(buf), 0);
dump_msg(buf, ret);
}
zmq_close (dealer);
zmq_ctx_destroy(context);
return 0;
}