0MQ opts not to add a new set of Application Programming Interfaces (APIs) but extends the existing socket API already familiar to programmers. Indeed, the semantics are only trivially different. This also translates into performance that matches and sometimes exceeds traditional socket programming.
Socket programmers are used to treating data as a stream with no inherent record structure. They’ll typically prefix a message with a length field, and once that length field is received, they use that length to issue the recv() call until that length has been met. So, the code fragment ends up looking something like the top portion of Figure 1 (error conditions ignored).
With 0MQ, the programming, as shown in the bottom half of Figure 1, is simpler. Conventional sockets typically present a synchronous interface to either connection-oriented reliable byte streams or connectionless unreliable datagrams. 0MQ sockets present an abstraction of an asynchronous message queue, with the exact queuing semantics dependant on the socket type in use. Where conventional sockets transfer streams of bytes or discrete datagrams, 0MQ sockets transfer discrete messages. 0MQ dictates no internal format for the message (e.g., additional headers, etc.) but treats the contents as an opaque “blob.”
According to “0MQ – The Guide” (http://zguide.zeromq.org/chapter:all), other attributes of messages include:
- 0MQ sends and receives messages atomically (i.e., you get a whole message or you don’t get one at all).
- 0MQ doesn’t necessarily send messages right away, but rather later, at some indeterminate time.
- You can send zero-length messages (e.g., for sending a signal from one thread to another).
- A message must fit in memory. If you want to send files of arbitrary sizes, you need to break them into pieces and send each piece as a separate message.
The programmer has a choice of transport mechanisms for his or her messages, but the message handling APIs are identical. The programmer informs 0MQ of the socket type to use at the start of processing, then uses the same set of calls to send/receive/poll the connections (see Figures 2 and 3).
The high water mark is a hard limit on the maximum number of outstanding messages 0MQ can queue in memory for any single peer with which the specified socket is communicating. 0MQ separates the types of messaging from the underlying transport protocol and provides a simple URL-like syntax for specifying that (e.g., tcp://host.ex.org:9999/). You can use several types of transports when you call zmq_bind and zmq_connect: