使用zmsg_send循环发消息前2条可达第3条丢失,求解决方案
Hey there, let's figure out why your third message isn't getting through when using zmsg_send in a loop with a REQ socket. This is a super common gotcha with ØMQ's REQ-REP pattern, so let's break it down and fix it.
The Root Cause
ØMQ's REQ socket enforces a strict request-reply sequence: you can only send a new request after receiving a reply to the previous one. Your first two messages might seem to work because ØMQ buffers them internally, but once the buffer hits its limit (or the socket enforces the protocol rule), the third send will block or fail entirely. If you're not handling replies in your loop, that's exactly what's happening here.
Feasible Solutions
1. Always Receive a Reply After Sending a Request
Modify your client code to wait for a server reply after each zmsg_send. This is non-negotiable for REQ sockets. Here's a corrected version of your code with proper request-reply handling:
#include <zmq.h> #include <czmq.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> void main(void) { int major, minor, patch; zmq_version(&major, &minor, &patch); printf("Current ØMQ version is %d.%d.%d\n", major, minor, patch); // Create REQ socket zsock_t *client = zsock_new(ZMQ_REQ); if (!client) { fprintf(stderr, "Failed to create REQ socket: %s\n", zmq_strerror(errno)); return; } // Connect to server (update the address to match your server) int rc = zsock_connect(client, "tcp://localhost:5555"); if (rc != 0) { fprintf(stderr, "Failed to connect to server: %s\n", zmq_strerror(errno)); zsock_destroy(&client); return; } // Send 3 messages, each followed by a reply for (int i = 0; i < 3; i++) { // Create and populate message zmsg_t *msg = zmsg_new(); if (!msg) { fprintf(stderr, "Failed to create message %d\n", i+1); break; } zmsg_addstr(msg, "Request #%d", i+1); // Send the message rc = zmsg_send(&msg, client); if (rc == -1) { fprintf(stderr, "Failed to send message %d: %s\n", i+1, zmq_strerror(errno)); zmsg_destroy(&msg); break; } printf("Sent message %d successfully\n", i+1); // Wait for server reply (critical step!) msg = zmsg_recv(client); if (!msg) { fprintf(stderr, "Failed to receive reply for message %d: %s\n", i+1, zmq_strerror(errno)); break; } printf("Received reply for message %d\n", i+1); zmsg_destroy(&msg); } // Cleanup zsock_destroy(&client); }
2. Ensure Your Server Replies to Every Request
Your server must use a REP socket and send a reply immediately after receiving each request. If the server doesn't reply, the client will hang waiting for a response, and subsequent sends will fail. Here's a minimal working server example:
#include <zmq.h> #include <czmq.h> #include <stdio.h> void main(void) { zsock_t *server = zsock_new(ZMQ_REP); zsock_bind(server, "tcp://*:5555"); printf("Server listening on tcp://*:5555\n"); while (1) { // Receive client request zmsg_t *msg = zmsg_recv(server); if (!msg) break; printf("Received client request\n"); // Send reply back zmsg_t *reply = zmsg_new(); zmsg_addstr(reply, "Acknowledged"); zmsg_send(&reply, server); zmsg_destroy(&msg); } zsock_destroy(&server); }
3. Debugging Tips
- Check return values: Always verify the result of
zmsg_sendandzmsg_recv—if they return-1orNULL, usezmq_strerror(errno)to get a detailed error message. - Enable verbose logging: Run your program with the
ZMQ_VERBOSE=1environment variable to see internal ØMQ events, which can help identify buffer or protocol issues. - Consider alternative sockets: If you don't need strict request-reply ordering, use a DEALER socket instead of REQ—DEALER allows unrestricted sending and receiving without protocol constraints.
内容的提问来源于stack exchange,提问作者Linus-Steve Gates

