DOKK / manpages / debian 10 / libczmq-dev / zframe.3.en
ZFRAME(3) CZMQ Manual ZFRAME(3)

zframe - Class for working with single message frames

//  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. 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); #endif // CZMQ_BUILD_DRAFT_API Please add '@interface' section in './../src/zframe.c'.

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.

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 (&copy); 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")); #if defined (__WINDOWS__) zsys_shutdown(); #endif

The czmq manual was written by the authors in the AUTHORS file.

Main web site:

Report bugs to the email <zeromq-dev@lists.zeromq.org[1]>

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.

1.
zeromq-dev@lists.zeromq.org
mailto:zeromq-dev@lists.zeromq.org
03/03/2019 CZMQ 4.2.0