zframe(3)
Class for working with single message frames
Description
ZFRAME
NAME
zframe - Class for working with single message frames
SYNOPSIS
// This is a
stable class, and may not change except for emergencies. It
// is provided in stable builds.
// This class has draft methods, which may change over time.
They are not
// in stable releases, by default. Use --enable-drafts to
enable.
#define ZFRAME_MORE 1 //
#define ZFRAME_REUSE 2 //
#define ZFRAME_DONTWAIT 4 //
// Create a new
frame. If size is not null, allocates the frame data
// to the specified size. If additionally, data is not null,
copies
// size octets from the specified data into the frame body.
CZMQ_EXPORT zframe_t *
zframe_new (const void *data, size_t size);
// Create an
empty (zero-sized) frame
CZMQ_EXPORT zframe_t *
zframe_new_empty (void);
// Create a
frame with a specified string content.
CZMQ_EXPORT zframe_t *
zframe_from (const char *string);
// Receive frame
from socket, returns zframe_t object or NULL if the recv
// was interrupted. Does a blocking recv, if you want to not
block then use
// zpoller or zloop.
CZMQ_EXPORT zframe_t *
zframe_recv (void *source);
// Destroy a
frame
CZMQ_EXPORT void
zframe_destroy (zframe_t **self_p);
// Send a frame
to a socket, destroy frame after sending.
// Return -1 on error, 0 on success.
CZMQ_EXPORT int
zframe_send (zframe_t **self_p, void *dest, int flags);
// Return number
of bytes in frame data
CZMQ_EXPORT size_t
zframe_size (zframe_t *self);
// Return
address of frame data
CZMQ_EXPORT byte *
zframe_data (zframe_t *self);
// Return meta
data property for frame
// The caller shall not modify or free the returned value,
which shall be
// owned by the message.
CZMQ_EXPORT const char *
zframe_meta (zframe_t *self, const char *property);
// Create a new
frame that duplicates an existing frame. If frame is null,
// or memory was exhausted, returns null.
// Caller owns return value and must destroy it when done.
CZMQ_EXPORT zframe_t *
zframe_dup (zframe_t *self);
// Return frame
data encoded as printable hex string, useful for 0MQ UUIDs.
// Caller must free string when finished with it.
// Caller owns return value and must destroy it when done.
CZMQ_EXPORT char *
zframe_strhex (zframe_t *self);
// Return frame
data copied into freshly allocated string
// Caller must free string when finished with it.
// Caller owns return value and must destroy it when done.
CZMQ_EXPORT char *
zframe_strdup (zframe_t *self);
// Return TRUE
if frame body is equal to string, excluding terminator
CZMQ_EXPORT bool
zframe_streq (zframe_t *self, const char *string);
// Return frame
MORE indicator (1 or 0), set when reading frame from socket
// or by the zframe_set_more() method
CZMQ_EXPORT int
zframe_more (zframe_t *self);
// Set frame
MORE indicator (1 or 0). Note this is NOT used when sending
// frame to socket, you have to specify flag explicitly.
CZMQ_EXPORT void
zframe_set_more (zframe_t *self, int more);
// Return TRUE
if two frames have identical size and data
// If either frame is NULL, equality is always false.
CZMQ_EXPORT bool
zframe_eq (zframe_t *self, zframe_t *other);
// Set new
contents for frame
CZMQ_EXPORT void
zframe_reset (zframe_t *self, const void *data, size_t
size);
// Send message
to zsys log sink (may be stdout, or system facility as
// configured by zsys_set_logstream). Prefix shows before
frame, if not null.
// Long messages are truncated.
CZMQ_EXPORT void
zframe_print (zframe_t *self, const char *prefix);
// Probe the
supplied object, and report if it looks like a zframe_t.
CZMQ_EXPORT bool
zframe_is (void *self);
// Self test of
this class.
CZMQ_EXPORT void
zframe_test (bool verbose);
#ifdef
CZMQ_BUILD_DRAFT_API
// Destroy an item
typedef void (zframe_destructor_fn) (
void **hint);
// *** Draft
method, for development use, may change without warning ***
// Create a new frame from memory. Take ownership of the
memory and calling the destructor
// on destroy.
CZMQ_EXPORT zframe_t *
zframe_frommem (void *data, size_t size,
zframe_destructor_fn destructor, void *hint);
// *** Draft
method, for development use, may change without warning ***
// Return frame routing ID, if the frame came from a
ZMQ_SERVER socket.
// Else returns zero.
CZMQ_EXPORT uint32_t
zframe_routing_id (zframe_t *self);
// *** Draft
method, for development use, may change without warning ***
// Set routing ID on frame. This is used if/when the frame
is sent to a
// ZMQ_SERVER socket.
CZMQ_EXPORT void
zframe_set_routing_id (zframe_t *self, uint32_t
routing_id);
// *** Draft
method, for development use, may change without warning ***
// Return frame group of radio-dish pattern.
CZMQ_EXPORT const char *
zframe_group (zframe_t *self);
// *** Draft
method, for development use, may change without warning ***
// Set group on frame. This is used if/when the frame is
sent to a
// ZMQ_RADIO socket.
// Return -1 on error, 0 on success.
CZMQ_EXPORT int
zframe_set_group (zframe_t *self, const char *group);
// *** Draft
method, for development use, may change without warning ***
// Send message to zsys log sink (may be stdout, or system
facility as
// configured by zsys_set_logstream). Prefix shows before
frame, if not null.
// Message length is specified; no truncation unless length
is zero.
// Backwards compatible with zframe_print when length is
zero.
CZMQ_EXPORT void
zframe_print_n (zframe_t *self, const char *prefix, size_t
length);
#endif //
CZMQ_BUILD_DRAFT_API
Please add '@interface' section in './../src/zframe.c'.
DESCRIPTION
The zframe class provides methods to send and receive single message frames across 0MQ sockets. A frame corresponds to one zmq_msg_t. When you read a frame from a socket, the zframe_more() method indicates if the frame is part of an unfinished multipart message. The zframe_send method normally destroys the frame, but with the ZFRAME_REUSE flag, you can send the same frame many times. Frames are binary, and this class has no special support for text data.
Please add @discuss section in ./../src/zframe.c.
EXAMPLE
From zframe_test method.
// Create two
PAIR sockets and connect over TCP
zsock_t *output = zsock_new (ZMQ_PAIR);
assert (output);
int port = zsock_bind (output,
"tcp://127.0.0.1:*");
assert (port != -1);
zsock_t *input = zsock_new (ZMQ_PAIR);
assert (input);
rc = zsock_connect (input, "tcp://127.0.0.1:%d",
port);
assert (rc != -1);
// Send five
different frames, test ZFRAME_MORE
int frame_nbr;
for (frame_nbr = 0; frame_nbr < 5; frame_nbr++) {
frame = zframe_new ("Hello", 5);
assert (frame);
rc = zframe_send (&frame, output, ZFRAME_MORE);
assert (rc == 0);
}
// Send same frame five times, test ZFRAME_REUSE
frame = zframe_new ("Hello", 5);
assert (frame);
for (frame_nbr = 0; frame_nbr < 5; frame_nbr++) {
rc = zframe_send (&frame, output, ZFRAME_MORE +
ZFRAME_REUSE);
assert (rc == 0);
}
assert (frame);
zframe_t *copy = zframe_dup (frame);
assert (zframe_eq (frame, copy));
zframe_destroy (&frame);
assert (!zframe_eq (frame, copy));
assert (zframe_size (copy) == 5);
zframe_destroy (©);
assert (!zframe_eq (frame, copy));
// Test
zframe_new_empty
frame = zframe_new_empty ();
assert (frame);
assert (zframe_size (frame) == 0);
zframe_destroy (&frame);
// Send END
frame
frame = zframe_new ("NOT", 3);
assert (frame);
zframe_reset (frame, "END", 3);
char *string = zframe_strhex (frame);
assert (streq (string, "454E44"));
freen (string);
string = zframe_strdup (frame);
assert (streq (string, "END"));
freen (string);
rc = zframe_send (&frame, output, 0);
assert (rc == 0);
// Read and
count until we receive END
frame_nbr = 0;
for (frame_nbr = 0;; frame_nbr++) {
zframe_t *frame = zframe_recv (input);
if (zframe_streq (frame, "END")) {
zframe_destroy (&frame);
break;
}
assert (zframe_more (frame));
zframe_set_more (frame, 0);
assert (zframe_more (frame) == 0);
zframe_destroy (&frame);
}
assert (frame_nbr == 10);
#if
(ZMQ_VERSION >= ZMQ_MAKE_VERSION (4, 1, 0))
// Test zframe_meta
frame = zframe_new ("Hello", 5);
assert (frame);
rc = zframe_send (&frame, output, 0);
assert (rc == 0);
frame = zframe_recv (input);
const char *meta = zframe_meta (frame,
"Socket-Type");
assert (meta != NULL);
assert (streq (meta, "PAIR"));
assert (zframe_meta (frame, "nonexistent") ==
NULL);
zframe_destroy (&frame);
#endif
zsock_destroy
(&input);
zsock_destroy (&output);
#if defined
(ZMQ_SERVER)
// Create server and client sockets and connect over inproc
zsock_t *server = zsock_new_server
("inproc://zframe-test-routing");
assert (server);
zsock_t *client = zsock_new_client
("inproc://zframe-test-routing");
assert (client);
// Send request
from client to server
zframe_t *request = zframe_new ("Hello", 5);
assert (request);
rc = zframe_send (&request, client, 0);
assert (rc == 0);
assert (!request);
// Read request
and send reply
request = zframe_recv (server);
assert (request);
assert (zframe_streq (request, "Hello"));
assert (zframe_routing_id (request));
zframe_t *reply
= zframe_new ("World", 5);
assert (reply);
zframe_set_routing_id (reply, zframe_routing_id (request));
rc = zframe_send (&reply, server, 0);
assert (rc == 0);
zframe_destroy (&request);
// Read reply
reply = zframe_recv (client);
assert (zframe_streq (reply, "World"));
assert (zframe_routing_id (reply) == 0);
zframe_destroy (&reply);
// Client and
server disallow multipart
frame = zframe_new ("Hello", 5);
rc = zframe_send (&frame, client, ZFRAME_MORE);
assert (rc == -1);
rc = zframe_send (&frame, server, ZFRAME_MORE);
assert (rc == -1);
zframe_destroy (&frame);
zsock_destroy
(&client);
zsock_destroy (&server);
#endif
#ifdef
ZMQ_RADIO
// Create radio and dish sockets and connect over inproc
zsock_t *radio = zsock_new_radio
("inproc://zframe-test-radio");
assert (radio);
zsock_t *dish = zsock_new_dish
("inproc://zframe-test-radio");
assert (dish);
// Join the
group
rc = zsock_join (dish, "World");
assert (rc == 0);
// Publish
message from radio
zframe_t *message = zframe_new ("Hello", 5);
assert (message);
rc = zframe_set_group (message, "World");
assert (rc == 0);
rc = zframe_send (&message, radio, 0);
assert (rc == 0);
assert (!message);
// Receive the
message from dish
message = zframe_recv (dish);
assert (message);
assert (zframe_streq (message, "Hello"));
assert (strcmp("World", zframe_group (message)) ==
0);
zframe_destroy (&message);
zsock_destroy
(&dish);
zsock_destroy (&radio);
#else
frame = zframe_new ("Hello", 5);
rc = zframe_set_group (frame, "World");
assert(rc == -1);
assert(errno == ENOTSUP);
zframe_destroy (&frame);
#endif
char str[] =
"hello";
frame = zframe_frommem (str, 5, mem_destructor, str);
assert (frame);
zframe_destroy (&frame);
// The
destructor doesn't free the memory, only changing the strid,
// so we can check if the destructor was invoked
assert (streq (str, "world"));
// zframe_print tests
zsys_set_logstream(verbose ? stdout : NULL);
// == No data
==
frame = zframe_new ("", 0);
// no prefix,
backwards compatible
// - emits nothing but the timestamp
zframe_print (frame, "");
zframe_print_n (frame, "", 0);
// prefix,
backwards compatible
// - emits nothing but the timestamp
zframe_print (frame, "Prefix");
zframe_print_n (frame, "Prefix", 0);
// len >
data
// - emits nothing but the timestamp
zframe_print_n (frame, "", 15);
zframe_print_n (frame, "Prefix", 15);
// max len
// - emits nothing but the timestamp
zframe_print_n (frame, "", -1);
zframe_print_n (frame, "Prefix", -1);
zframe_destroy (&frame);
// == Short
data ==
frame = zframe_new ("Hello there!", 12);
// no prefix,
backwards compatible: ellipsis
// - "[012] Hello there!"
zframe_print (frame, "");
zframe_print_n (frame, "", 0);
// prefix,
backwards compatible: ellipsis
// - "Prefix[012] Hello there!"
zframe_print (frame, "Prefix");
zframe_print_n (frame, "Prefix", 0);
// len <
data
// - "[012] Hello"
// - "Prefix[012] Hello"
zframe_print_n (frame, "", 5);
zframe_print_n (frame, "Prefix", 5);
// len >
data
// - "[012] Hello there!"
// - "Prefix[012] Hello there!"
zframe_print_n (frame, "", 15);
zframe_print_n (frame, "Prefix", 15);
// max len
// - "[012] Hello there!"
// - "Prefix[012] Hello there!"
zframe_print_n (frame, "", -1);
zframe_print_n (frame, "Prefix", -1);
zframe_destroy (&frame);
// == Long data
==
frame = zframe_new ("Lorem ipsum dolor sit amet,
consectetur adipiscing elit. Proin finibus ligula et aliquam
tristique. Phasellus consequat, enim et blandit varius,
sapien diam faucibus lorem, non ultricies lacus turpis sed
lectus. Vivamus id elit urna. In sit amet lacinia mauris.
Class aptent taciti sociosqu ad litora torquent per conubia
nostra, per inceptos himenaeos. Integer ut cursus diam.
Vestibulum semper vel leo eu finibus. Ut urna magna, commodo
vel auctor sed, eleifend quis lacus. Aenean quis ipsum et
velit auctor ultrices.", 519);
// no prefix,
backwards compatible: ellipsis
// - "[070] Lorem ipsum dolor sit amet, consectetur
adipiscing elit. Proin finibus..."
zframe_print (frame, "");
zframe_print_n (frame, "", 0);
// prefix,
backwards compatible: ellipsis
// - "Prefix[070] Lorem ipsum dolor sit amet,
consectetur adipiscing elit. Proin finibus..."
zframe_print (frame, "Prefix");
zframe_print_n (frame, "Prefix", 0);
// len <
data
// - "[519] Lorem"
// - "Prefix[519] Lorem"
zframe_print_n (frame, "", 5);
zframe_print_n (frame, "Prefix", 5);
// small len
// - "[519] Lorem ipsum dolor sit amet"
// - "Prefix[519] Lorem ipsum dolor sit amet"
zframe_print_n (frame, "", 26);
zframe_print_n (frame, "Prefix", 26);
// mid len
// - "[519] Lorem ipsum dolor sit amet, consectetur
adipiscing elit. Proin finibus"
// "[519] ligula et aliquam tristique. Phasellus
consequat, enim et blandit var"
// "[519] ius, sapie"
// - "Prefix[519] Lorem ipsum dolor sit amet,
consectetur adipiscing elit. Proin finibus"
// "Prefix[519] ligula et aliquam tristique. Phasellus
consequat, enim et blandit var"
// "Prefix[519] ius, sapie"
zframe_print_n (frame, "", 150);
zframe_print_n (frame, "Prefix", 150);
// len >
data
// - emits the whole paragraph
zframe_print_n (frame, "", 1500);
zframe_print_n (frame, "Prefix", 1500);
// max len
// - emits the whole paragraph
zframe_print_n (frame, "", -1);
zframe_print_n (frame, "Prefix", -1);
zframe_destroy (&frame);
#if defined
(__WINDOWS__)
zsys_shutdown();
#endif
AUTHORS
The czmq manual was written by the authors in the AUTHORS file.
RESOURCES
Main web site:
Report bugs to the email <zeromq-dev@lists.zeromq.org [1] >
COPYRIGHT
Copyright (c) the Contributors as noted in the AUTHORS file. This file is part of CZMQ, the high-level C binding for 0MQ: http://czmq.zeromq.org. This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. LICENSE included with the czmq distribution.
NOTES
|
1. |
zeromq-dev@lists.zeromq.org |
mailto:zeromq-dev@lists.zeromq.org